A program which's main never gets called

Pages: 12
Oct 19, 2013 at 2:16am
BHXSpecter: the function will execute though. It is initializing a global variable. And, you could, theoretically put all running code inside getInt and ignore main() altogether.

EDIT: I tried the code, and it crashed after about 100 Hello Worlds.
Screen shot:
http://puu.sh/4TAiA.png
Last edited on Oct 19, 2013 at 2:19am
Oct 19, 2013 at 2:23am
Then that means every book ever written on C++ is wrong. "The execution of your program always start at main"
Oct 19, 2013 at 2:24am
Try it yourself. They are right in their own way. But it is possible to run the program without main.

EDIT: The program won't link without a main of some sort. But it is possible to run the program without main ever being called.
Last edited on Oct 19, 2013 at 2:29am
Oct 19, 2013 at 5:08am
Well, I even have an issue with the standard as it is written/worded.

Section 3.6.1/1
A program shall contain a global function called main, which is the designated start of the program.


Interpretation is key, and since they say 'program' I interpret that as meaning the executable and not the code. Because of my interpretation of that line to me it seems odd that it would execute anything outside of main if it is never called by main.

It is obvious I don't know enough about the standard. The more I learn the less confident I feel in my ability to use it.
Oct 19, 2013 at 5:17am
This global function "main" is present. It just does not get called yet. That is the beginning of a program if there are no global variables to initialize. That is not the case with int z; which is initialized with a function thus, this code(getInt) gets called before main.
Oct 19, 2013 at 5:22am
closed account (S6k9GNh0)
BHXSpecter, it's a flaw in design in my opinion (although probably intended). Things that are global space, especially class instances with default constructors, have to be initialized at some point, specifically sometime before main is executed. It's not meant to be used as a vantage point like described by OP and there's probably some side effects. I wouldn't recommend it.

This type of functionality can also be used in C (if the compiler supports it) by using extensions: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

EDIT: A slight explanation of how execution before main works on Linux https://blogs.oracle.com/ksplice/entry/hello_from_a_libc_free
Last edited on Oct 19, 2013 at 5:36am
Oct 19, 2013 at 6:05am
It is (usually) false that execution begins in main but the textbooks aren't "wrong"; it's an abstraction, they're hiding implementation details that you don't need to know. For all intents and purposes, execution begins in main. A C++ implementation can do whatever it wants and still be conformant to the standard, so long as the programmer can't tell the difference between what the standard specifies and what's really happening.

The GNU toolchain actually inserts an _start routine which sets up some registers, allocates a stack and then calls a function called _init, followed by __libc_start_main which calls main, and then when main exits a function called _fini is called.

You can actually disable the _start routine on gcc with the -nostartfiles option, and then you can do this:
1
2
3
4
5
6
#include <stdio.h>

void _start(void)
{
    printf("hello, world\n");
}

It will work, but it will cause a segmentation fault when it tries to return using a non-existent stack. You can also tell ld to use a different entry point than _start so that you can have a program that really does start at main, although I wouldn't recommend it because then you won't have a stack or any constructors or destructors for your global variables unless you do that yourself.

You can verify that main isn't called when you define _start for yourself and compile with -nostartfiles:
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>

void _start(void)
{
    return;
}

int main(void)
{
    printf("hello, world\n");
    return 0;
}

This code will also segfault and will not print anything.

And here's a something for fun: http://codepad.org/WLn9pBYZ
Oct 19, 2013 at 7:24am
The GNU toolchain actually inserts an _start routine which sets up some registers, allocates a stack
This statement contradicts the following:
It will work, but it will cause a segmentation fault when it tries to return using a non-existent stack.
If the stack is allocated by _start(), it would not be possible to call printf() without crashing.
The reason _start() crashes upon returning is because it's supposed to never return. It's supposed to call _exit() instead, which itself should ask the system to cleanup the process.

More info on this subject: http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html

By the way, the order of initialization of globals is undefined, so referencing a global (e.g. std::cout) within a function that's called during initialization of another global has undefined behavior. Just figured I'd mention it.
Oct 19, 2013 at 4:30pm
closed account (Dy7SLyTq)
Is that how at_exit() works then?
Topic archived. No new replies allowed.
Pages: 12