Is it OK to use longjmp to break out of qsort?

In In the middle of qsort, is there a way to stop it? some comments mentioned using setjmp/longjmp to break out of a call to qsort() from the comparison function.

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

Does the lack of mention mean it’s implicitly allowed or is it undefined behavior because the result is not explicitly defined?

I think it’s obvious that the state of the array being sorted would be indeterminate. But could it have more wide-ranging impact?

7

I argue that the behavior is undefined under many, if not all, conditions. (To be precise, I don’t think the longjmp in and of itself necessarily causes UB, but I think it will be difficult or impossible to avoid having the program’s subsequent execution cause UB.)

This is based on 7.1.4p4 (C23 N3220):

The functions in the standard library are not guaranteed to be reentrant and may modify objects
with static or thread storage duration.

Now, the standard does not define “reentrant”. But at the least, this forbids a comparison function from calling qsort recursively. So it seems to permit an implementation like

void qsort(...) {
    _Thread_local bool inside_qsort = false;
    if (inside_qsort)
        summon_nasal_demons();
    inside_qsort = true;
    // ... body ...
    inside_qsort = false;
}

If longjmp were called from the comparison function, 7.13.3.1/2-3 (as mentioned in other answers) actually guarantees that inside_qsort must retain the value true, such that any future calls to qsort would summon the demons. So at the very least, I think we can say that if you longjmp out of qsort, you cannot safely call qsort again during the execution of the program.

A trickier question is whether you can safely call any other library function. The common situation where the non-reentrancy of 7.1.4p4 comes up is signal handlers. In that setting, it’s understood that it forbids calling any library function from a signal handler that may have interrupted a library function – not just the same one. For instance, even if you can prove that the only library function your signal handler could have interrupted was fgetc, that does not mean the handler can safely call fscanf.

Based on that logic, we might argue that if you longjmp out of qsort, it is undefined behavior to call any library function from that point onward, including such functions as exit and abort, which are hard to avoid (recall that returning from main is equivalent to calling exit, 5.1.2.3.4p1).

On the other hand, that same logic would lead us to the conclusion that it is unsafe to call any library function from within a qsort comparison function. And it’s obvious that at least some library functions were intended to be guaranteed safe in that context, such for instance strcmp, although this is nowhere explicitly stated. So perhaps there would be some library functions that you could safely call after longjmp out of qsort, but the standard never says what they are.

2

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

qsort() is distinguished by being one of the very few standard library functions that relies on a user-supplied callback. You are right that its specifications don’t say what happens if a call to the comparison callback does not return, so there is at least room for question. But this seems only slightly distinguished from the case where the same thing happens in a user-defined callback-based sort function. I don’t see a good reason not to expect the behavior to follow longjmp()‘s specifications:

The longjmp function restores the environment saved by the most recent invocation of the setjmp
macro in the same invocation of the program with the corresponding jmp_buf argument. […]

All accessible objects have values, and all other components of the abstract machine have state,
as of the time the longjmp function was called, except that the representation of objects of automatic
storage duration that are local to the function containing the invocation of the corresponding
setjmp macro that do not have volatile-qualified type and have been changed between the setjmp
invocation and longjmp call is indeterminate.

(C23 7.13.3.1/2-3)

I take that as a definition of what happens, so the behavior is not undefined.

As you observe, however, we must allow that qsort() may have made unspecified changes of substantially any nature to the contents of the array prior to the longjmp call. It may also be that qsort() dynamically allocates memory, which would presumably be leaked by the longjmp. These are the kinds of issues that attend longjmp calls generally.

4

The only caveat I found has to do with where the array being sorted resides relative to the setjmp call prior to calling qsort.

Section 7.13.2.1 regarding the longjmp function states the following:

All accessible objects have values, and all other components of the
abstract machine have state, as of the time the longjmp function
was called, except that the values of objects of automatic storage
duration that are local to the function containing the invocation of
the corresponding setjmp macro that do not have volatile-qualified
type and have been changed between the setjmp invocation and longjmp
call are indeterminate.

So if the array to be sorted is defined in the same function that setjmp is called from, its contents become indeterminate and attempting to access those contents will trigger undefined behavior.

If the array is not defined in the function where setjmp is called, the array contents seem to be at most unspecified and not indeterminate.

Based on this, it seems the behavior is well-defined provided the above caveat is avoided. However, there is still the possibility of a memory leak depending on the implementation of qsort.

IMHO, this is not really specific to qsort. The fact is that any function that is active between the call to setjump and the call to longjump will have no possibility to clean any state. State here may refer to allocated memory, or any other thread or static variable. So if one of those functions is neither user provided and re-entrant nor non-user provided and explicitly marked as re-entrant, calling it again may involve undefined behaviour.

Said differently, you can safely use any variable that was defined before the call to the function containing the call to setjump(*) and any function that was never called or that could return before the call to longjump.

Here, my understanding is that calling again qsort would be undefined by the language, but provided the array was defined before the call to the function containing setjump(*), you can safely save it to a disk file and terminate the program.


(*) Section 7.13.2 §3 regarding the longjmp function states (emphasis mine):

All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.

2

The Standard is somewhat vague with respect to the internals of qsort, in large measure because any tasks where such details would matter could be accomplished with a user-code function that either behaves just like qsort in all documented respects, or behaves in some other way which is even better suited to the actual tasks at hand.

The C language and Standard Library evolved in an era before many of today’s commonplace text-processing or other tools existed, and where the fastest way to accomplish many tasks would be to write a quick “throwaway” C program to accomplish precisely what needed to be done. Since many tasks would require sorting, having a qsort() function available was more convenient than having to write a sorting function every time one wanted to write a quick C program that involved sorting.

It seems doubtful that a competently written qsort() function would need to expressly allocate any outside storage, since an implementation that always sub-sorts whichever partition is found to be smaller before doing the other one will never need to keep track of more than log₂N levels of pending sub-sort operations, and few execution environments would have trouble declaring a couple of automatic-duration arrays of log₂SIZE_MAX values of type size_t. Nonetheless, it would be plausible that an implementation might use a variable-length array, and the Standard expressly notes that VLA storage might leak (I know of at least one embedded implementation that uses malloc/free for VLA storage).

I would thus recommend that any program that might need to longjmp out of a quick sort operation include its own version of quick sort rather than using the library version. Indeed, I’d probably recommend that programs implement their own sorting functions in any case. In cases where e.g. one will want to sort a bunch of pointers to some kind of structure, an implementation of qsort which uses pointer assignments rather than memcpy will likely be faster than one which is completely agnostic with regard to what is being stored, and one won’t have to guess whether an implementation might use variable length arrays or other external storage.

4

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Is it OK to use longjmp to break out of qsort?

In In the middle of qsort, is there a way to stop it? some comments mentioned using setjmp/longjmp to break out of a call to qsort() from the comparison function.

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

Does the lack of mention mean it’s implicitly allowed or is it undefined behavior because the result is not explicitly defined?

I think it’s obvious that the state of the array being sorted would be indeterminate. But could it have more wide-ranging impact?

7

I argue that the behavior is undefined under many, if not all, conditions. (To be precise, I don’t think the longjmp in and of itself necessarily causes UB, but I think it will be difficult or impossible to avoid having the program’s subsequent execution cause UB.)

This is based on 7.1.4p4 (C23 N3220):

The functions in the standard library are not guaranteed to be reentrant and may modify objects
with static or thread storage duration.

Now, the standard does not define “reentrant”. But at the least, this forbids a comparison function from calling qsort recursively. So it seems to permit an implementation like

void qsort(...) {
    _Thread_local bool inside_qsort = false;
    if (inside_qsort)
        summon_nasal_demons();
    inside_qsort = true;
    // ... body ...
    inside_qsort = false;
}

If longjmp were called from the comparison function, 7.13.3.1/2-3 (as mentioned in other answers) actually guarantees that inside_qsort must retain the value true, such that any future calls to qsort would summon the demons. So at the very least, I think we can say that if you longjmp out of qsort, you cannot safely call qsort again during the execution of the program.

A trickier question is whether you can safely call any other library function. The common situation where the non-reentrancy of 7.1.4p4 comes up is signal handlers. In that setting, it’s understood that it forbids calling any library function from a signal handler that may have interrupted a library function – not just the same one. For instance, even if you can prove that the only library function your signal handler could have interrupted was fgetc, that does not mean the handler can safely call fscanf.

Based on that logic, we might argue that if you longjmp out of qsort, it is undefined behavior to call any library function from that point onward, including such functions as exit and abort, which are hard to avoid (recall that returning from main is equivalent to calling exit, 5.1.2.3.4p1).

On the other hand, that same logic would lead us to the conclusion that it is unsafe to call any library function from within a qsort comparison function. And it’s obvious that at least some library functions were intended to be guaranteed safe in that context, such for instance strcmp, although this is nowhere explicitly stated. So perhaps there would be some library functions that you could safely call after longjmp out of qsort, but the standard never says what they are.

2

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

qsort() is distinguished by being one of the very few standard library functions that relies on a user-supplied callback. You are right that its specifications don’t say what happens if a call to the comparison callback does not return, so there is at least room for question. But this seems only slightly distinguished from the case where the same thing happens in a user-defined callback-based sort function. I don’t see a good reason not to expect the behavior to follow longjmp()‘s specifications:

The longjmp function restores the environment saved by the most recent invocation of the setjmp
macro in the same invocation of the program with the corresponding jmp_buf argument. […]

All accessible objects have values, and all other components of the abstract machine have state,
as of the time the longjmp function was called, except that the representation of objects of automatic
storage duration that are local to the function containing the invocation of the corresponding
setjmp macro that do not have volatile-qualified type and have been changed between the setjmp
invocation and longjmp call is indeterminate.

(C23 7.13.3.1/2-3)

I take that as a definition of what happens, so the behavior is not undefined.

As you observe, however, we must allow that qsort() may have made unspecified changes of substantially any nature to the contents of the array prior to the longjmp call. It may also be that qsort() dynamically allocates memory, which would presumably be leaked by the longjmp. These are the kinds of issues that attend longjmp calls generally.

4

The only caveat I found has to do with where the array being sorted resides relative to the setjmp call prior to calling qsort.

Section 7.13.2.1 regarding the longjmp function states the following:

All accessible objects have values, and all other components of the
abstract machine have state, as of the time the longjmp function
was called, except that the values of objects of automatic storage
duration that are local to the function containing the invocation of
the corresponding setjmp macro that do not have volatile-qualified
type and have been changed between the setjmp invocation and longjmp
call are indeterminate.

So if the array to be sorted is defined in the same function that setjmp is called from, its contents become indeterminate and attempting to access those contents will trigger undefined behavior.

If the array is not defined in the function where setjmp is called, the array contents seem to be at most unspecified and not indeterminate.

Based on this, it seems the behavior is well-defined provided the above caveat is avoided. However, there is still the possibility of a memory leak depending on the implementation of qsort.

IMHO, this is not really specific to qsort. The fact is that any function that is active between the call to setjump and the call to longjump will have no possibility to clean any state. State here may refer to allocated memory, or any other thread or static variable. So if one of those functions is neither user provided and re-entrant nor non-user provided and explicitly marked as re-entrant, calling it again may involve undefined behaviour.

Said differently, you can safely use any variable that was defined before the call to the function containing the call to setjump(*) and any function that was never called or that could return before the call to longjump.

Here, my understanding is that calling again qsort would be undefined by the language, but provided the array was defined before the call to the function containing setjump(*), you can safely save it to a disk file and terminate the program.


(*) Section 7.13.2 §3 regarding the longjmp function states (emphasis mine):

All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.

2

The Standard is somewhat vague with respect to the internals of qsort, in large measure because any tasks where such details would matter could be accomplished with a user-code function that either behaves just like qsort in all documented respects, or behaves in some other way which is even better suited to the actual tasks at hand.

The C language and Standard Library evolved in an era before many of today’s commonplace text-processing or other tools existed, and where the fastest way to accomplish many tasks would be to write a quick “throwaway” C program to accomplish precisely what needed to be done. Since many tasks would require sorting, having a qsort() function available was more convenient than having to write a sorting function every time one wanted to write a quick C program that involved sorting.

It seems doubtful that a competently written qsort() function would need to expressly allocate any outside storage, since an implementation that always sub-sorts whichever partition is found to be smaller before doing the other one will never need to keep track of more than log₂N levels of pending sub-sort operations, and few execution environments would have trouble declaring a couple of automatic-duration arrays of log₂SIZE_MAX values of type size_t. Nonetheless, it would be plausible that an implementation might use a variable-length array, and the Standard expressly notes that VLA storage might leak (I know of at least one embedded implementation that uses malloc/free for VLA storage).

I would thus recommend that any program that might need to longjmp out of a quick sort operation include its own version of quick sort rather than using the library version. Indeed, I’d probably recommend that programs implement their own sorting functions in any case. In cases where e.g. one will want to sort a bunch of pointers to some kind of structure, an implementation of qsort which uses pointer assignments rather than memcpy will likely be faster than one which is completely agnostic with regard to what is being stored, and one won’t have to guess whether an implementation might use variable length arrays or other external storage.

4

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa

Is it OK to use longjmp to break out of qsort?

In In the middle of qsort, is there a way to stop it? some comments mentioned using setjmp/longjmp to break out of a call to qsort() from the comparison function.

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

Does the lack of mention mean it’s implicitly allowed or is it undefined behavior because the result is not explicitly defined?

I think it’s obvious that the state of the array being sorted would be indeterminate. But could it have more wide-ranging impact?

7

I argue that the behavior is undefined under many, if not all, conditions. (To be precise, I don’t think the longjmp in and of itself necessarily causes UB, but I think it will be difficult or impossible to avoid having the program’s subsequent execution cause UB.)

This is based on 7.1.4p4 (C23 N3220):

The functions in the standard library are not guaranteed to be reentrant and may modify objects
with static or thread storage duration.

Now, the standard does not define “reentrant”. But at the least, this forbids a comparison function from calling qsort recursively. So it seems to permit an implementation like

void qsort(...) {
    _Thread_local bool inside_qsort = false;
    if (inside_qsort)
        summon_nasal_demons();
    inside_qsort = true;
    // ... body ...
    inside_qsort = false;
}

If longjmp were called from the comparison function, 7.13.3.1/2-3 (as mentioned in other answers) actually guarantees that inside_qsort must retain the value true, such that any future calls to qsort would summon the demons. So at the very least, I think we can say that if you longjmp out of qsort, you cannot safely call qsort again during the execution of the program.

A trickier question is whether you can safely call any other library function. The common situation where the non-reentrancy of 7.1.4p4 comes up is signal handlers. In that setting, it’s understood that it forbids calling any library function from a signal handler that may have interrupted a library function – not just the same one. For instance, even if you can prove that the only library function your signal handler could have interrupted was fgetc, that does not mean the handler can safely call fscanf.

Based on that logic, we might argue that if you longjmp out of qsort, it is undefined behavior to call any library function from that point onward, including such functions as exit and abort, which are hard to avoid (recall that returning from main is equivalent to calling exit, 5.1.2.3.4p1).

On the other hand, that same logic would lead us to the conclusion that it is unsafe to call any library function from within a qsort comparison function. And it’s obvious that at least some library functions were intended to be guaranteed safe in that context, such for instance strcmp, although this is nowhere explicitly stated. So perhaps there would be some library functions that you could safely call after longjmp out of qsort, but the standard never says what they are.

2

The language specification doesn’t seem to say what happens in this case. The only constraint on the comparison function explicitly mentioned is that it must return consistent results.

qsort() is distinguished by being one of the very few standard library functions that relies on a user-supplied callback. You are right that its specifications don’t say what happens if a call to the comparison callback does not return, so there is at least room for question. But this seems only slightly distinguished from the case where the same thing happens in a user-defined callback-based sort function. I don’t see a good reason not to expect the behavior to follow longjmp()‘s specifications:

The longjmp function restores the environment saved by the most recent invocation of the setjmp
macro in the same invocation of the program with the corresponding jmp_buf argument. […]

All accessible objects have values, and all other components of the abstract machine have state,
as of the time the longjmp function was called, except that the representation of objects of automatic
storage duration that are local to the function containing the invocation of the corresponding
setjmp macro that do not have volatile-qualified type and have been changed between the setjmp
invocation and longjmp call is indeterminate.

(C23 7.13.3.1/2-3)

I take that as a definition of what happens, so the behavior is not undefined.

As you observe, however, we must allow that qsort() may have made unspecified changes of substantially any nature to the contents of the array prior to the longjmp call. It may also be that qsort() dynamically allocates memory, which would presumably be leaked by the longjmp. These are the kinds of issues that attend longjmp calls generally.

4

The only caveat I found has to do with where the array being sorted resides relative to the setjmp call prior to calling qsort.

Section 7.13.2.1 regarding the longjmp function states the following:

All accessible objects have values, and all other components of the
abstract machine have state, as of the time the longjmp function
was called, except that the values of objects of automatic storage
duration that are local to the function containing the invocation of
the corresponding setjmp macro that do not have volatile-qualified
type and have been changed between the setjmp invocation and longjmp
call are indeterminate.

So if the array to be sorted is defined in the same function that setjmp is called from, its contents become indeterminate and attempting to access those contents will trigger undefined behavior.

If the array is not defined in the function where setjmp is called, the array contents seem to be at most unspecified and not indeterminate.

Based on this, it seems the behavior is well-defined provided the above caveat is avoided. However, there is still the possibility of a memory leak depending on the implementation of qsort.

IMHO, this is not really specific to qsort. The fact is that any function that is active between the call to setjump and the call to longjump will have no possibility to clean any state. State here may refer to allocated memory, or any other thread or static variable. So if one of those functions is neither user provided and re-entrant nor non-user provided and explicitly marked as re-entrant, calling it again may involve undefined behaviour.

Said differently, you can safely use any variable that was defined before the call to the function containing the call to setjump(*) and any function that was never called or that could return before the call to longjump.

Here, my understanding is that calling again qsort would be undefined by the language, but provided the array was defined before the call to the function containing setjump(*), you can safely save it to a disk file and terminate the program.


(*) Section 7.13.2 §3 regarding the longjmp function states (emphasis mine):

All accessible objects have values, and all other components of the abstract machine have state, as of the time the longjmp function was called, except that the values of objects of automatic storage duration that are local to the function containing the invocation of the corresponding setjmp macro that do not have volatile-qualified type and have been changed between the setjmp invocation and longjmp call are indeterminate.

2

The Standard is somewhat vague with respect to the internals of qsort, in large measure because any tasks where such details would matter could be accomplished with a user-code function that either behaves just like qsort in all documented respects, or behaves in some other way which is even better suited to the actual tasks at hand.

The C language and Standard Library evolved in an era before many of today’s commonplace text-processing or other tools existed, and where the fastest way to accomplish many tasks would be to write a quick “throwaway” C program to accomplish precisely what needed to be done. Since many tasks would require sorting, having a qsort() function available was more convenient than having to write a sorting function every time one wanted to write a quick C program that involved sorting.

It seems doubtful that a competently written qsort() function would need to expressly allocate any outside storage, since an implementation that always sub-sorts whichever partition is found to be smaller before doing the other one will never need to keep track of more than log₂N levels of pending sub-sort operations, and few execution environments would have trouble declaring a couple of automatic-duration arrays of log₂SIZE_MAX values of type size_t. Nonetheless, it would be plausible that an implementation might use a variable-length array, and the Standard expressly notes that VLA storage might leak (I know of at least one embedded implementation that uses malloc/free for VLA storage).

I would thus recommend that any program that might need to longjmp out of a quick sort operation include its own version of quick sort rather than using the library version. Indeed, I’d probably recommend that programs implement their own sorting functions in any case. In cases where e.g. one will want to sort a bunch of pointers to some kind of structure, an implementation of qsort which uses pointer assignments rather than memcpy will likely be faster than one which is completely agnostic with regard to what is being stored, and one won’t have to guess whether an implementation might use variable length arrays or other external storage.

4

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật