1

C11 5.1.2.2.1 says

it [main()] shall be defined with a return type of int

However, section 6.7.4 introduces the _Noreturn keyword, which seems to be very useful for the main() of bare-bone embedded systems.

What is the most elegant way to declare a non-returnable main()? Is it _Noreturn int main(void)?

Vorac
  • 8,726
  • 11
  • 58
  • 101
  • 3
    What is the point of this? Why not just use `int main(void)`? It's standard, portable and non-gcc specific. – user694733 Dec 12 '13 at 10:03
  • 2
    @user694733 Because he is using a barebone embedded system where 1) `int main (void)` doesn't make any sense and 2) `void main (void)` is 100% standard and 100% portable. [Read this](http://stackoverflow.com/questions/5296163/why-is-the-type-of-the-main-function-in-c-and-c-left-to-the-user-to-define/5296593#5296593). – Lundin Dec 12 '13 at 10:59
  • (...and then people keep up-voting the comment of some confused PC programmer. Wish you could down vote comments.) – Lundin Dec 12 '13 at 11:06
  • It's embedded - who cares if it's never going to return anyway. I just don't understand the concern at all. It's a non-issue, surely? – Martin James Dec 12 '13 at 11:32
  • @MartinJames, 1) intent, 2) sometimes saving a couple of bytes does matter. It's a very small issue, I confess. – Vorac Dec 12 '13 at 12:01
  • @Lundin Except that I am **not** PC programmer, but embedded systems programmer, and so far toolchains have worked with `int main(void)` in freestanding systems just fine, and compilers have worked it out. – user694733 Dec 12 '13 at 12:34
  • @Lundin It seems you are right about standard allowing other return types than `int`. `void main(void)` is not 100% portable though (IAR arm compiler for example). – user694733 Dec 12 '13 at 12:45
  • 1
    @MartinJames Usually, bare bone embedded systems start execution from a reset ISR, which in turn calls main. If the calling convention of main is `int main()` then the reset ISR will make room for the return value on the stack, even though main() will never return. – Lundin Dec 12 '13 at 12:51
  • @user694733 It will probably work, not because the compiler "worked it out", but rather because you sacrifice some bytes on the stack, for no reason (you create a memory leak on the stack). If you are on a low-end 8-bit MCU with a limited stack, this will matter a lot. On a larger system, less so. – Lundin Dec 12 '13 at 12:54
  • @Lundin No. In IAR for example, `int main(void)` is the *only* supported form, so it wasn't me that made the "sacrifice". But as compiler in question is smart enough, it treats `main` as special function, and not reserve those useless bytes on stack. That's what I meant with "working it out". But at least we could agree that there is no 100% portable `main` function when it comes to embedded world. – user694733 Dec 12 '13 at 13:05

3 Answers3

3

You are reading the wrong part of the standard. 5.1.2.2.1 is a subclause of 5.1.2.2 Hosted environment. A barebone embedded system is not a hosted system, it is a freestanding system. So the cited text is irrelevant. More info here.

The most portable way to declare main in a freestanding environment is void main (void).

As already mentioned in another answer, the gcc compiler option is -ffreestanding

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
1

Your objectives are contradictory. You cannot ask for a compiler flag that is not compiler specific.

That said, for gcc it is: -ffreestanding.

-ffreestanding

Assert that compilation takes place in a freestanding environment.
 This implies `-fno-builtin'.  A freestanding environment is one in
 which the standard library may not exist, and program startup may
 not necessarily be at `main'.  The most obvious example is an OS
 kernel.  This is equivalent to `-fno-hosted'.
rodrigo
  • 94,151
  • 12
  • 143
  • 190
0

You missed the end of the phrase "or in some other implementation-defined manner". So your implementation, that is your platform, not you as a programmer, may foresee a different return type of main, and some platforms do.

Also according to C99 and C11, you are not forced to specify a return value for main. The platform is supposed to do reasonable things, when you return from main, if you do it ever.

In any case, main is special and obeys special rules. Trust your platform provider that it does the right thing for it. You are talking of a completely negligible optimization, in case your main really does never return.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • No, he is reading the wrong chapter of the standard. The phrase about "implementation-defined manner" applies to the _parameters_ of main in a _hosted_ system and thus it is completely irrelevant. – Lundin Dec 12 '13 at 11:01
  • @Lundin You're right that it applies to hosted systems, but not that it only applies to the parameters of `main`. This is why 5.1.2.2.3 (still part of 5.1.2.2) starts with "If the return type of the main function is a type compatible with int". –  Dec 12 '13 at 11:07
  • @hvd 5.1.2.2.3 ends with `If the return type is not compatible with int, the termination status returned to the host environment is unspecified`. Unspecified and impl.defined are two different things. This might actually be an inconsistency in the C standard. _However_, it doesn't matter since this question isn't about hosted systems. – Lundin Dec 12 '13 at 11:09
  • @Lundin I see no inconsistency. Whether `void main(void)` is valid at all is implementation-defined. If it's valid, a program uses it, and the program stops by returning from `main`, the termination status is unspecified. They are two different things, so one can be implementation-defined while the other is unspecified. Agreed that it doesn't matter for this question, commenting anyway because it may still be of interest. –  Dec 12 '13 at 11:16
  • @lundin, no I don't think that it only applies to the parameters. The whole phrase starts *"It shall be defined with a return type of `int`.."* and the semicolon and "or" referes to the whole phrase that is before it. As you can see from the non-caps that are used after it, the ":" doesn't terminate the phrase. – Jens Gustedt Dec 12 '13 at 11:20