Live data from Hacker News

What happens before main() is executed in C and why is it important?

mymicrocontroller.com

41–50 of 104 posts

Re: What happens before main() is executed in C and why is it important?

#41
you can have pre-main functions in in C as well (as a GCC extension). If you define functions with `__attribute__(constructor)` and they will be called before main(). You can even set the priority on them, and set post-main destructor callbacks. This works even for shared libraries loaded in run-time.

I've used this as a trick to automatically run unit tests, though, not for any real work.

Re: What happens before main() is executed in C and why is it important?

#42
post #22

Earlier quoted context omitted.

> relying on static initialization is something one should think about potentially solving differently This is such a notorious problem, it even has a name: Static Initialisation Order Fiasco (see: https://isocpp.org/wiki/faq/ctors#static-init-order ) The symmetrical Static Destruction Order Fiasco is also a very fun problem to deal with. The solution proposed for SIOF in the C++ FAQ does nothing to help you deal wit…

Perhaps worse, lots of new languages, for example Go, copied this mistake from C++. :(

Is the "static initialization order fiasco" a thing that can happen in go? The order of package level variable initialization is well defined in the spec and because go doesn't allow import cycles it seems like the issue mentioned in the linked page is not possible.

Re: What happens before main() is executed in C and why is it important?

#43
post #31

Earlier quoted context omitted.

It's not just "good practice", but instead the startup code is so specific to the platform that there really isn't "generic" startup code.

The generic compiler-provided startup code is fine for AVRs under most circumstances, since they're only produced by a single manufacturer and don't have fancy features like PLLs which need to be initialized. It's the more complicated chips where it gets a little hairy, especially if you have to deal with things like external RAM.

There actually isn't any reason STM or NXP or whatever ARM vendor couldn't provide AVR-like usability and awesome libc. For example the assembly blobs used on most STM32s are very simple.

It's simply that they want to push people to their propietary IDEs (to increase vendor lock in). STM used to provide an okayish libc implementation but then decided to bury it inside CUBE (MX).

If your design becomes complicated enough sure go ahead and change the startup code. But that's quite a small portion of all uses and for those we should have AVR like ease of use.

Re: What happens before main() is executed in C and why is it important?

#44

Earlier quoted context omitted.

The article is not advocating initializing the stack pointer with a C++ constructor.

> * Memory segments are initialized. Memory segments such as .bss (for uninitialized data), .data (for initialized data such as static variables, global variables, local static variables, addresses of functions, and function pointers), and .text (where the actual code resides) are initialized and a valid stack is set up. > * Command line arguments are received. This may not be relevant in embedded systems as in embed…

The article is conflating two things:

* What happens before main()

* What can you do to make code run before main()

It suggests only the avenue of C++ global constructors to make code run before main() (as others have noted, __attribute__((constructor)) is basically the same thing for C). But there are other ways to make code run before main, such as by use of linker scripts and assembly files to put code in _start that eventually calls main() (note that it's this latter way by which all of the things they mention are done).

Re: What happens before main() is executed in C and why is it important?

#45
post #42

Earlier quoted context omitted.

Perhaps worse, lots of new languages, for example Go, copied this mistake from C++. :(

Is the "static initialization order fiasco" a thing that can happen in go? The order of package level variable initialization is well defined in the spec and because go doesn't allow import cycles it seems like the issue mentioned in the linked page is not possible.

Static initialization order may be defined, but that doesn't mean it's easy to reason about.

Re: What happens before main() is executed in C and why is it important?

#46
post #31

Earlier quoted context omitted.

The generic compiler-provided startup code is fine for AVRs under most circumstances, since they're only produced by a single manufacturer and don't have fancy features like PLLs which need to be initialized. It's the more complicated chips where it gets a little hairy, especially if you have to deal with things like external RAM.

There actually isn't any reason STM or NXP or whatever ARM vendor couldn't provide AVR-like usability and awesome libc. For example the assembly blobs used on most STM32s are very simple. It's simply that they want to push people to their propietary IDEs (to increase vendor lock in). STM used to provide an okayish libc implementation but then decided to bury it inside CUBE (MX). If your design becomes complicated eno…

The choice of board support stuff like crystal frequency is stuff that needs to be tweaked per board really early in the boot process.

Re: What happens before main() is executed in C and why is it important?

#47
post #41

you can have pre-main functions in in C as well (as a GCC extension). If you define functions with `__attribute__(constructor)` and they will be called before main(). You can even set the priority on them, and set post-main destructor callbacks. This works even for shared libraries loaded in run-time. I've used this as a trick to automatically run unit tests, though, not for any real work.

"Yeah, yeah, but your scientists were so preoccupied with whether or not they could that they didn't stop to think if they should."

Re: What happens before main() is executed in C and why is it important?

#48
post #41

you can have pre-main functions in in C as well (as a GCC extension). If you define functions with `__attribute__(constructor)` and they will be called before main(). You can even set the priority on them, and set post-main destructor callbacks. This works even for shared libraries loaded in run-time. I've used this as a trick to automatically run unit tests, though, not for any real work.

"Yeah, yeah, but your scientists were so preoccupied with whether or not they could that they didn't stop to think if they should."

It can be useful for registering things automatically, like Go's init() functions which I've used on occasion.

Re: What happens before main() is executed in C and why is it important?

#49
post #14

Personally, I think global's with constructors are kind of an anti pattern. I've noticed a high correlation between crappy app's and app's with a lot of pre main() code. Especially if some of your global's have threads: because then you potentially have threads running AFTER main exits... I've seen a number of apps with random crashes at shutdown because a thread that was started in a global was still running and sin…

This is a real problem; i’m not sure rooting all mutable state on the stack will help in this case without language-level metadata restricting frees, passing references, and dereferencing.

It seems like the rust answer of making it difficult to share mutable state is a solid answer—you explicitly manage concurrent state, rather than implicitly allowing sharing. In addition rust has some interesting run-once constraints you can add to closures that work well with global initialization. I’ll admit I haven’t seen enough rust to see it work well in action, but the pieces are there.

Re: What happens before main() is executed in C and why is it important?

#50

Did someone on HN downvote everything except the bullet points in this article? Seriously-- why is the font greyed out? What possible purpose does this serve?

YMMD... seriously I opened the article only looked at the bullet points and than quickly discarded it...
Post reply on HN