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?

sasha.sochka
  • 14,395
  • 10
  • 44
  • 68

3 Answers3

25

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.
  • ...
Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
  • Interesting if that's possible to extend procedures which `exit` performs or even overload it. I should try – sasha.sochka Apr 09 '13 at 20:29
  • 4
    @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)`](http://linux.die.net/man/3/atexit) function. – Adam Rosenfield Apr 09 '13 at 20:32
  • 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. – Eric Postpischil Apr 09 '13 at 20:54
  • 1
    @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?" – Cogwheel Apr 09 '13 at 21:05
  • 1
    @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? – rubenvb Apr 09 '13 at 21:06
  • @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. – Eric Postpischil Apr 09 '13 at 21:09
  • @rubenvb: Saying the exit function flushes the open streams does not explain how the processor gets into the exit function. – Eric Postpischil Apr 09 '13 at 21:09
  • 2
    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. – Vinícius Gobbo A. de Oliveira Apr 09 '13 at 21:11
  • 1
    @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. – Eric Postpischil Apr 09 '13 at 21:26
  • 5
    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 Apr 09 '13 at 22:15
  • 1
    @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. – Vinícius Gobbo A. de Oliveira Apr 10 '13 at 13:52
  • @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. – Eric Postpischil Apr 10 '13 at 14:43
  • @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) – Vinícius Gobbo A. de Oliveira Apr 10 '13 at 14:58
  • @ViníciusGobboA.deOliveira: My answer is [here](http://stackoverflow.com/a/15912543/298225). 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. – Eric Postpischil Apr 10 '13 at 15:07
  • @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). – Vinícius Gobbo A. de Oliveira Apr 10 '13 at 15:15
  • @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." – Raymond Chen Apr 10 '13 at 17:00
  • Would love a link for these! – jvriesem May 03 '20 at 16:28
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.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
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.

K Scott Piel
  • 4,320
  • 14
  • 19