Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This patch undoes a patch submitted by Cristian Maglie <c.maglie@ardu…
…ino.cc> on Tue Oct 11 18:36:08 2016 (ce89e7e). Why: Construction of global objects is something which needs be done prior running main(). It has been like this since the conception of Unix and the C language that was created to write Unix in and since then standardized in the Portable Operating System Interface (POSIX): Initialization of memory is done by entry point _start() which does stuff like loading commandline arguments from the stack and runs main() with it, and calls _exit() on return of main(). The function _exit() in the old-time days of mainframes was responsible for flushing buffers and relinquish all other resources (memory, sockets etc.) such the next user/program can use them (nowadays operating systems are smarter and got your back if programs fail to do this properly). On embedded systems (such as those running Arduino) there is no program loader or operating system, meaning these duties are to be done by what is commonly referred to as the Reset Handler, being the entry point of the program like _start() is on a POSIX-compliant machine. By moving the duties of _start() to main() itself a variety of problems may arise involving a variety of static initialization problems that are very hard to spot. And if not today there will be in the future because the current behavior is not expected. (It is anti-logical; things that are to be done prior main() should not be in main() itself.) If this breaks libraries, it means these unnamed "some libraries" are broken: Things like hardware init should be in begin(), not a class constructor. And most definitely should one class constructor never rely on another class constructor having done something already, like initializing hardware. This is because the compiler has no good control over what class is initialized first: All the compiler can do is specify an order of importance, which the linker then must be instructed to follow, which the C library then needs to run correctly in that order. None of the problems that occur due to one of those steps going not as expected are easy to spot or in any way obvious from C/C++ code. Or easy to fix for that matter. And none of this is formally specified and hence implementation-specific. Type "The Static Initialization Order Fiasco" into a search engine of your choice. Or, to cut this story down to the shortest possible way to put it: Constructors are for creating constructs in memory, nothing else. Procedural code does not belong there, it should be in begin(). Any library needing Cristian Maglie's hack is broken and should be fixed. Compromising Arduino core is not a fix.
- Loading branch information