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…
What happens before main() is executed in C and why is it important?
51–60 of 104 posts
Re: What happens before main() is executed in C and why is it important?
#52Earlier quoted context omitted.
> * 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…
You can't really initialize the stack pointer in a constructor, or indeed in C++ at all; there's no syntax for it and the compiler may use the stack to allocate local variables in the function prologue.
It's an absolutely terrible idea, but I've seen engineers be so afraid of asm files that they'd try something like this.
Re: What happens before main() is executed in C and why is it important?
#53Earlier 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++. :(
Re: What happens before main() is executed in C and why is it important?
#54Nit: that’s not the best wording. if the executable is being executed by something like `exec` then these are just “arguments”; the command line (i.e. a shell) isn’t involved. Do embedded systems support something like `exec`?
Re: What happens before main() is executed in C and why is it important?
#55Earlier 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.
I guess I rarely see the case for an AVR when you're not prototyping on an Arduino. You can get chips that are an order of magnitude more powerful per $/watt/and any other metric you'd want to use.
Re: What happens before main() is executed in C and why is it important?
#56Earlier quoted context omitted.
I guess I rarely see the case for an AVR when you're not prototyping on an Arduino. You can get chips that are an order of magnitude more powerful per $/watt/and any other metric you'd want to use.
Have you read "The Amazing $1 Microcontroller" [0], which might have been posted here before? It's a survey of available microcontrollers, with the intent of helping you choose one. If you have read it, are you in agreement with the article, for example on how AVRs compare to others? [0] https://jaycarlson.net/microcontrollers/
My biggest complaint though is that he expresses GPIO cycle time and interrupt latency in cycles, rather than normalized on real time.
Particularly when comparing a STM32F0 to an AVR, the perf looks almost even, until you realize that the STM32F0 is clocked 2.5x faster.
Re: What happens before main() is executed in C and why is it important?
#57 // Just tested with mingw-gcc on Win8.1
// Maybe you need to play around with the offset, +28
int main() {
int i; // Another stack variable
printf("%d\n", (long long)&i + 28); // &argv
printf("%d\n", *((void**)((long long)&i + 28))); // argv
printf("%s\n", ((char**)*((void**)((long long)&i + 28)))[0]); // argv[0]
return 0;
}
Exclaimer: I don't know how this behaves in an embedded environment.Re: What happens before main() is executed in C and why is it important?
#58Earlier 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.
I guess I rarely see the case for an AVR when you're not prototyping on an Arduino. You can get chips that are an order of magnitude more powerful per $/watt/and any other metric you'd want to use.
Re: What happens before main() is executed in C and why is it important?
#59Re: What happens before main() is executed in C and why is it important?
#60To me one curious thing about the main() function without arguments is, these arguments are still pushed onto the stack. You can find them by dereferencing a pointer of another stack variable and playing around with the offset. // Just tested with mingw-gcc on Win8.1 // Maybe you need to play around with the offset, +28 int main() { int i; // Another stack variable printf("%d\n", (long long)&i + 28); // &argv printf(…