I know that in computers, value returned by the main() function is received by the operating system. But, what happens in the main() function of a microcontroller?

  • 7
    \$\begingroup\$ I always use void main() when I am using C for PIC microcontrollers. When using C compilers for microcontrollers, it really does not matter at all. Because there is no operating system that runs the (say) "main.c". If there is something like RTOS running in that microcontroller, then the operating system is the "main.c". \$\endgroup\$ – abdullah kahraman Jan 22 '13 at 16:44
  • 4
    \$\begingroup\$ Not realy a duplicate, but at least related: electronics.stackexchange.com/q/30830/4950 \$\endgroup\$ – PetPaulsen Jan 22 '13 at 17:15
  • 1
    \$\begingroup\$ How the startup function is defined is usually not up to you to decide. The environment you're using will document the supported startup function forms. Hosted C implementations are required to support two forms of main with two different signatures, both of which return int. If you're using a freestanding C implementation, that implementation dictates how you should write the startup function. You can't write a void returning function just because it doesn't return. The behavior of not returning is different from the function type which influences the overall calling conventions. \$\endgroup\$ – Kaz Jan 23 '13 at 0:43

On a microcontroller, main() is not really expected to ever exit, and the behavior if it does is not defined — so it's up to whoever wrote the C runtime for the microcontroller. I've seen systems that:

  • Have an implicit loop around main(), so that if it exits, it simply gets called again.
  • Have a simple "jump-to-self" loop that gets executed if main() ever exits.
  • Simply execute the rest of code memory that follows the call to main(). This is called "running off into the weeds".

I've never seen one that actually does anything at all with the value returned by main(). If this is something you actually care about, then you should take a look at — and possibly modify — the source code for your system's C runtime library.

  • 1
    \$\begingroup\$ You beat me to it. +1 for synchronicity. \$\endgroup\$ – Adam Lawrence Jan 22 '13 at 16:53
  • 9
    \$\begingroup\$ The C standard defining main() to have an int return value obviously was not designed with an OS-less microcontroller in mind. So this is unspecified behaviour and anything might happen depending on your C runtime, as Dave listed. \$\endgroup\$ – ndim Jan 22 '13 at 17:32
  • 4
    \$\begingroup\$ C running on an OS-less microcontroller could be considered a freestanding implementation, and the C standard doesn't even require a freestanding environent to have a main(), much less define its return value. That's up to the implementor. \$\endgroup\$ – KutuluMike Jan 22 '13 at 21:05
  • 2
    \$\begingroup\$ @ndim - to split hairs, void main( void ) is implementation defined behaviour, not unspecified behaviour. \$\endgroup\$ – Andrew Jan 22 '13 at 21:42
  • 1
    \$\begingroup\$ @MichaelEdenfield: Indeed. However, all code in C is defined in terms of functions, so it is never possible to have a fresstanding system completely written in C; there needs to be at least a tiny bit of assembly language (or whatever) that sets up a minimal environment so that a C function can be called. The most obvious name for that function is main(). \$\endgroup\$ – Dave Tweed Jan 22 '13 at 22:08

A common misunderstanding/myth is that int main is the only valid form specified by the standard. That is not true.

The C standard speaks of two implementations: hosted and freestanding. "Implementation" in this case means compiler. Hosted compilers compile for a specific OS and freestanding compilers compile for a specific bare metal application. Embedded systems are almost always freestanding systems - even in the case of RTOS.

Freestanding implementations may use any form for main(), they don't even need to have a function called main. Most often, they use the form void main (void), since it doesn't make any sense to return anything.

What's important to realize here is that it is always the compiler that decides the form of main() and never the programmer.

Freestanding implementations that do return something from main() are very questionable. Makes you wonder if the people who made the compiler actually read the standard...

Details here.


The C language standard allows for the implementation defined variation void main( void ) and this is the usual form in embedded systems - simply because they are not expected to return.

If you look at the compiler setup, there is usually a bootstrap snippet of code, called from the reset vector, which performs some basic initialisation (including eg coping of initialisation values into variables) before calling main().

This will also (usually) be within an infinite loop, or perhaps perform a reset, if main() returns


It (as other answers mentioned) depends on your toolchain, but for example in GCC main is compiled as other functions, so its return value will be stored accordingly to calling conventions (on ARM I am using right not with GCC it will be put to R0 just before return).

I guess that is is simillar on AVR-GCC, so custom script can use this value after main returns.

  • \$\begingroup\$ this rather misses the point \$\endgroup\$ – Chris Stratton Aug 8 '14 at 22:02
  • \$\begingroup\$ It emphasizes that the one who calls main can get its return value. Of course it is ignored in 99.9% situations, but answer provides information who can receive this return value. \$\endgroup\$ – kwesolowski Aug 8 '14 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.