in reply to Re^4: porting C code to Perl
in thread porting C code to Perl

So you're saying that this code:

#include <stdio.h> int value; void main(void) { printf("%d\n", value); }

may output something else then 0 on these platforms/compilers? Looking at ANSI C (as the smallest common base) I would say these compilers are in violation of the C Standard and cannot be truly called C. (But I may be wrong - I'm not a greybearded C guru.)

From the C89 standard, section 3.5.7

If an object that has static storage duration is not initialized explicitly, it is initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.

(I am deliberately quoting C89 and not a more recent standard too make sure this isn't a later addition / clarification.)

Replies are listed 'Best First'.
Re^6: porting C code to Perl [OT]
by haukex (Archbishop) on Oct 25, 2017 at 10:14 UTC
    So you're saying that this code ... may output something else then 0 on these platforms/compilers?

    Yes, exactly. Of course, this was something like over five years ago and the compiler may very well be obsolete by now. I don't have much time right now to dig out references, but based on my memory, this was either on a Microchip PIC or TI MSP430, and the gist of it was this: Say you defined a 256-byte char array as a global variable, then what this compiler would do to initialize it is create 256 null bytes in instruction memory, and copy those over to RAM byte by byte. Of course on a tiny uC that was a huge waste of instruction memory, and it was much better to drop that initialization routine (or the compiler did this by default, I don't remember exactly), leave the variables uninitialized, and just write a for loop to initialize them yourself, or use memset, which amounts to the same thing.

    Since these are uCs without an OS, one might suspect that when the uC starts it jumps right into main (since that's basically what it does when you code in assembly), but that's not the case - C needs a bit of initialization (like setting up interrupt vectors), so the compiler had some per-uC assembler files that took over the initialization tasks and that were set up to run on startup; these assembly routines would then do their thing and jump into main. And IIRC there were different versions of these initialization routines, some that would initialize global memory and some that wouldn't, and you could even hack them yourself if you needed custom initialization. AFAIK more modern compilers have much more efficient code to initialize RAM, but basically the thing I took away from this was to always be suspicious of uninitialized variables in C :-)