C에서 exit ()를 사용해야합니까?
C ++에서 사용 하는 것에 대한 질문 이 있습니다 exit
. 대답은 주로 RAII로 인해 좋은 생각이 아니라는 것을 설명합니다. 예를 들어 exit
코드의 어딘가에서 호출 되면 객체의 소멸자가 호출되지 않으므로 예를 들어 소멸자가 파일에 데이터를 쓰려는 경우에는 이런 일이 발생하지 않습니다. , 소멸자가 호출되지 않았기 때문입니다.
C에서이 상황이 어떻게 나타나는지 관심이있었습니다. 비슷한 문제가 C에서도 적용됩니까? C에서는 생성자 / 소멸자를 사용하지 않기 때문에 C에서는 상황이 다를 수 있다고 생각했습니다. C에서 사용해도 괜찮 exit
습니까?
나는 아래와 같은 함수를 보았는데, 어떤 경우에는 사용하기에 좋지만 exit
C ++에서 위에서 설명한 것처럼를 사용하여 C에서 비슷한 문제가 있으면 관심이 있습니까? (아래와 같은 기능을 사용하는 것은 좋지 않습니다.)
void die(const char *message)
{
if(errno) {
perror(message);
} else {
printf("ERROR: %s\n", message);
}
exit(1);
}
대신 C abort()
의 exit()
함수는 "정상적인"종료로 간주됩니다.
C11에서 (N1570) 7.22.4.4/p2 종료 기능 (강조 내) :
이
exit
기능은 정상적인 프로그램 종료를 발생시킵니다.
표준은 또한 7.22.4.4/p4에서 다음과 같이 말합니다.
다음으로 버퍼링되지 않은 데이터가있는 모든 열린 스트림이 플러시 되고 모든 열린 스트림이 닫히고
tmpfile
함수에 의해 생성 된 모든 파일 이 제거됩니다.
7.21.3 / p5 파일 도 살펴볼 가치가 있습니다 .
는 IF
main
경우 원래의 호출자에게 함수가 반환이, 또는exit
함수가 호출 될 때, 열려있는 모든 파일이 닫혀 프로그램 종료 전에 (따라서 모든 출력 스트림을 플러시).abort
함수 호출과 같은 프로그램 종료에 대한 다른 경로는 모든 파일을 제대로 닫을 필요가 없습니다.
그러나 아래 주석에서 언급했듯이 다른 모든 리소스 를 포함한다고 가정 할 수 없으므로 atexit()
해당 릴리스에 대한 콜백을 개별적으로 정의하고 정의 해야 할 수 있습니다 . 실제로 이것은 atexit()
7.22.4.2/p2에서 말하는 것처럼 정확히 의도 된 것 입니다 . atexit 함수 :
이
atexit
함수func
는 정상적인 프로그램 종료시 인수없이 호출되도록에서 가리키는 함수를 등록합니다 .
특히, C 표준은 할당 된 저장 기간 (예 :)의 객체에 대해 정확히 어떤 일이 발생해야하는지 정확히 말하지 않으므로 malloc()
특정 구현에서 어떻게 수행되는지 알아야합니다. 최신 호스트 지향 OS의 경우 시스템이 처리 할 가능성이 높지만 Valgrind 와 같은 메모리 디버거를 침묵시키기 위해 직접 처리 할 수 있습니다 .
예, exit
C 에서 사용 해도됩니다.
모든 버퍼와 정상적 종료를 보장하려면이 기능을 사용하는 것이 좋습니다 atexit
. 자세한 내용은 여기를 참조하세요.
예제 코드는 다음과 같습니다.
void cleanup(void){
/* example of closing file pointer and free up memory */
if (fp) fclose(fp);
if (ptr) free(ptr);
}
int main(int argc, char **argv){
/* ... */
atexit(cleanup);
/* ... */
return 0;
}
이제를 exit
호출 할 때마다 함수 cleanup
가 실행되어 정상적인 종료, 버퍼, 메모리 정리 등을 수용 할 수 있습니다.
생성자와 소멸자는 없지만 리소스 (예 : 파일, 스트림, 소켓)를 가질 수 있으며 올바르게 닫는 것이 중요합니다. 버퍼는 동 기적으로 기록 될 수 없으므로 리소스를 올바르게 닫지 않고 프로그램을 종료하면 손상 될 수 있습니다.
사용 exit()
OK
아직 언급되지 않은 코드 디자인의 두 가지 주요 측면은 '스레딩'과 '라이브러리'입니다.
In a single-threaded program, in the code you're writing to implement that program, using exit()
is fine. My programs use it routinely when something has gone wrong and the code isn't going to recover.
But…
However, calling exit()
is a unilateral action that can't be undone. That's why both 'threading' and 'libraries' require careful thought.
Threaded programs
If a program is multi-threaded, then using exit()
is a dramatic action which terminates all the threads. It will probably be inappropriate to exit the entire program. It may be appropriate to exit the thread, reporting an error. If you're cognizant of the design of the program, then maybe that unilateral exit is permissible, but in general, it will not be acceptable.
Library code
And that 'cognizant of the design of the program' clause applies to code in libraries, too. It is very seldom correct for a general purpose library function to call exit()
. You'd be justifiably upset if one of the standard C library functions failed to return just because of an error. (Obviously, functions like exit()
, _Exit()
, quick_exit()
, abort()
are intended not to return; that's different.) The functions in the C library therefore either "can't fail" or return an error indication somehow. If you're writing code to go into a general purpose library, you need to consider the error handling strategy for your code carefully. It should fit in with the error handling strategies of the programs with which it is intended to be used, or the error handling may be made configurable.
I have a series of library functions (in a package with header "stderr.h"
, a name which treads on thin ice) that are intended to exit as they're used for error reporting. Those functions exit by design. There are a related series of functions in the same package that report errors and do not exit. The exiting functions are implemented in terms of the non-exiting functions, of course, but that's an internal implementation detail.
I have many other library functions, and a good many of them rely on the "stderr.h"
code for error reporting. That's a design decision I made and is one that I'm OK with. But when the errors are reported with the functions that exit, it limits the general usefulness the library code. If the code calls the error reporting functions that do not exit, then the main code paths in the function have to deal with error returns sanely — detect them and relay an error indication to the calling code.
The code for my error reporting package is available in my SOQ (Stack Overflow Questions) repository on GitHub as files stderr.c
and stderr.h
in the src/libsoq sub-directory.
One reason to avoid exit
in functions other than main()
is the possibility that your code might be taken out of context. Remember, exit is a type of non local control flow. Like uncatchable exceptions.
For example, you might write some storage management functions that exit on a critical disk error. Then someone decides to move them into a library. Exiting from a library is something that will cause the calling program to exit in an inconsitent state which it may not be prepared for.
Or you might run it on an embedded system. There is nowhere to exit to, the whole thing runs in a while(1)
loop in main()
. It might not even be defined in the standard library.
Depending on what you are doing, exit may be the most logical way out of a program in C. I know it's very useful for checking to make sure chains of callbacks work correctly. Take this example callback I used recently:
unsigned char cbShowDataThenExit( unsigned char *data, unsigned short dataSz,unsigned char status)
{
printf("cbShowDataThenExit with status %X (dataSz %d)\n", status, dataSz);
printf("status:%d\n",status);
printArray(data,dataSz);
cleanUp();
exit(0);
}
In the main loop, I set everything up for this system and then wait in a while(1) loop. It is possible to make a global flag to exit the while loop instead, but this is simple and does what it needs to do. If you are dealing with any open buffers like files and devices you should clean them up before close for consistency.
It is terrible in a big project when any code can exit except for coredump. Trace is very import to maintain a online server.
참고URL : https://stackoverflow.com/questions/31501142/should-we-use-exit-in-c
'Program Tip' 카테고리의 다른 글
classList가있는 코드가 IE에서 작동하지 않습니까? (0) | 2020.10.14 |
---|---|
HTMLCollection, NodeLists 및 객체 배열의 차이점 (0) | 2020.10.14 |
R에서 두 목록을 결합하는 방법 (0) | 2020.10.14 |
네임 스페이스를 "사용하지"하려면 어떻게해야합니까? (0) | 2020.10.14 |
C #에서 system.net.webrequest를 사용하여 JSON 응답을 얻는 방법은 무엇입니까? (0) | 2020.10.14 |