Is there a guarantee of stdout auto-flush before exit? How does it work?
Asked Answered
Y

3

17

Here is the code (valid C and C++)

#include <stdio.h>

int main() {
    printf("asfd");
    // LINE 1
    return 0;
}

If in line 1 I put segfaulting expression the program would just crash without printing anything (as expected).

But why is the above code printing "asdf" and not exiting without buffer being flushed? What is under the hood and why does it work as expected?

Yount answered 9/4, 2013 at 20:8 Comment(2)
Don't use printf in C++!!Cauterize
note: this question is dual-tagged but the answer is different in C than in C++. Raymond Chen's answer covers C++. @JensGustedt 's answer covers C (but has been deleted...)Deviled
B
24

This is accomplished by these two sections in the C++ language specification:

[basic.start.main]

A return statement in main has the effect of leaving the main function and calling exit with the return value as the argument.

and

[lib.support.start.term]

The function exit has additional behavior in this International Standard:

  • ...
  • Next, all open C streams with unwritten buffered data are flushed.
  • ...
Beethoven answered 9/4, 2013 at 20:22 Comment(17)
Interesting if that's possible to extend procedures which exit performs or even overload it. I should tryYount
@sasha.sochka: You cannot overload the exit function; if you try, your function won't get called. You can, however, register functions to be called upon exiting using the atexit(3) function.Hindenburg
The question asks “What is under the hood?” I interpret this as asking how the behavior is implemented. This answer merely quotes the standard saying that it must be implemented.Departed
@Eric This gives a fine overview of how it's implemented; the exit function is called whenever the program ends, and that function flushes the buffer. What's lower level than that? "how do c compilers implement function calls?"Vaccinate
@Eric: the standard says exactly how it is implemented: the exit function flushes the open streams. I don't see how this does not answer the question?Expendable
@Matthew'Cogwheel'Orlando: This answer does not say how it is implemented. The quotes from the standard say a return statement “has the effect of leaving the main function and calling exit with the return value of the argument.” Furthermore, the standard does not say, as you do, “the exit function is called”. It only says that the effect is the same. When somebody asks for “under the hood”, you lift up the hood and look underneath.Departed
@rubenvb: Saying the exit function flushes the open streams does not explain how the processor gets into the exit function.Departed
The exactly bits of how it is implemented is different on each platform. Despite this, the specification is very clear about the steps to be performed before and after the execution of the main function, and was (at last for me) enough to have a very good overview of what happens under the hood.Neslund
@ViníciusGobboA.deOliveira: A basic question to be answered about the “under the hood” activity is this: Returning from main ends a program. Crashing with a segment fault ends a program. One of them flushes buffers. One of them does not. What happens inside the computer that makes one way of ending a program different from the other way of ending a program? Not why are they different, not what different effects are observed, but what actually happens differently in ending the process.Departed
If you really want to know what happens under the hood, use the debugger and step out of the main function and see where it goes!Beethoven
@EricPostpischil What happens inside the computer is implementation specific. You must debug (like previously mentioned) and study the operating system and compiler code. Code is implementation. And I don't think the question was specific to an Operating System. Under these general circumstances, I don't see why a conceptual answer isn't appropriate.Neslund
@ViníciusGobboA.deOliveira: The fact that what happens under the hood is implementation specific does not alter the fact that the question was asked, and it does not prevent us from answering. There is simply no reason to withhold this information. If somebody wants to write in portable C or C++, certainly they should stick to the standard. But if somebody wants to know what happens under the hood, that is fine too. Wanting to understand things is good and should be encouraged.Departed
@EricPostpischil I haven't seen you answer the question at all. The guidelines were given. If the author of the question wants more info, he could either modify his question to include more specific information or dig himself on books/code/anything-else-needed. Also, I should point that the author himself wrote in a previous comment: "If you really want to know what happens under the hood, use the debugger and step out of the main function and see where it goes!" (Raymond Chen)Neslund
@ViníciusGobboA.deOliveira: My answer is here. The person who wrote the comment about the debugger is not the person who asked us the question, so it does not inform us about the intent of the question. The question explicitly asks “What is under the hood?”, and it is nonsensical to say that the question can be answered by looking elsewhere, since the purpose of asking questions here is to get answers here, and this question, however interpreted, is suitable for Stack Overflow.Departed
@EricPostpischil Indeed, I have wrongly read the name of the author of the question. But I totally disagree that your answer is coherent with your arguments (just for your knowledge, I was the only one to +1 your answer so far).Neslund
@EricPostpischil I think you're reading too much into the question "What is under the hood?" If you read the context of the question, the OP was really asking, "How is this possible? The return statement at the end of main ends program execution!" The answer is, "No, the return statement at the end of main does not end program execution. According to the standard, there is other stuff that happens before execution finally terminates."Beethoven
Would love a link for these!Consanguinity
D
4

Generally, a return from main is not the end of your program, nor is entry to main the start.

Usually, the linker that creates the final executable for your program marks some location, perhaps named start, as the place where execution is to begin. When the operating system loads your program and starts executing it, it starts execution at this place. There is code there that sets up an environment: Creates a stack, sets stream states, et cetera. Then this code calls main.

When main returns, it returns to this special code. That code then performs various clean-up work that is required at the end of a C or C++ program, as described in this answer.

If a program is terminated abruptly, this final code might not be executed.

Departed answered 9/4, 2013 at 21:6 Comment(0)
C
2

When main() exits, all open streams are closed... to include stdout. Closing the open stream flushes stdout and what you've written to the buffer gets committed with or without the newline.

Clerihew answered 9/4, 2013 at 20:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.