This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

extern variable recognized improperly

Hi,

I ran into an issue where I had a variable, lets call it foo, declared globally in foo.c.

int foo = 0; // this is located globally in foo.c

I then assigned foo.c a variable in main.c

int main(void)

{

foo = 10;

}

The compiler accepted the code and compiled it.

When running my code in debug, everything was fine, until I compiled my code for flash execution and ran it as it would in the field.

My code was not running as expected.

I was able to find that I did not declare foo in main.c.

I then used the bad habit of declaring foo as extern in main.c.

extern int foo; // this was placed into main.c.

Then my code ran as expected when executing out of flash as it would in the field.

My biggest question is, why didn't the compiler refuse to compile the code prior to me declaring foo as an extern variable in main.c?

This shouldn't even be a warning, but a show stopper for the compiler.

I was also able to verify that foo was not declared anywhere else in main.c thinking that maybe it was being resolved to some local variable.

I'm using the C5515 with TI compiler 4.4.1.

After this little run in, I have decided to go through my code and eliminate the use of external variables.

Any input on what I have described would be appreciated.

Thanks!

  • Your question doesn't make much sense to me because you start by saying that you defined foo at the top of foo.c and then later say that you didn't.

    Regardless, I don't think the problem is what you think it is. First, your addition of the "extern" storage class specifier is redundant and should not have changed anything, because "extern" is the default storage class for declarations at the top level. Also, "extern" just means that the object has static extent and that it is known to the linker. It  doesn't mean that the defining declaration for the object definitely is in another file. It is perfectly fine for all declarations of the object to be "extern". One of them will be automatically chosen as the defining declaration.

    Second, in the C55xx devices code typically always executes from RAM. It may be loaded from an external serial Flash memory at startup by the bootloader, but thereafter it executes from RAM. I suspect the difference in your two cases is not where the code is executing from but how it got there: loaded by the bootloader from an external Flash memory or loaded directly from an attached debugger.

    Third, you should be aware that the startup code that is generated by the TI toolchain (the code that executes before main() is called) does not clear the BSS segment. This is a point of contention because the C language standard is pretty clear that you can rely on all variables with static storage class to be initialised to zero at startup. Nevertheless, it is not the case here and you cannot assume that an object declared without an explicit initialiser will be zero at program start. I think this issue is likely the root cause of your problems. When you load the image (code and data) in to the RAM from the debugger your variable ends up initialised differently from when the bootloader loads the RAM from Flash.

  • Benjamin, if I understand you correctly, you had a reference in file main.c to a variable which was not declared anywhere in main.c or any header file it includes, yet the compiler accepted it without a diagnostic. This should not be the case. Can you post a test case which demonstrates this problem?
  • Hi Archaeologist!

    Doing a small test case of this scenario does not reveal the issue I described.

    I know without being able to reproduce the issue there is not much that can be said or done.

    I'll have to investigate my project some more to see how it could have happened.

    It is a very large project with probably 200 source files that end up making an executable image that is 557KB big!

    It will take some time for me to pinpoint the issue or get it to a reproducible state because it literally takes 20 minutes to compile if I change certain aspects.

    I will keep you posted.

    Thanks!

  • Given your description, I would guess that there is a definition somewhere in a header file that main.c is including. You might try compiling with -ppc to preprocess main.c while keeping comments. You can then search main.pp for a declaration of foo.
  • Yes, you are correct!
    I had to do some digging, but I found an extern reference to foo in a *.h file which was eventually included in main.c.
    I will read up about the -ppc option.
    I'm still trying to setup the conditions that allowed this to slip past the compiler...
    Thanks.