Search code examples
ccompiler-warningspicmicrochipxc8

xc8 warning: initial value for var differs


I've been running into a compiler warning:

version.h:47: warning: (1478) initial value for "_svn_string_revision" differs to that in version.h:47

the corresponding version.h file looks like this:

#ifndef _VERSION_H_
#define _VERSION_H_

#define SVN_REVISION_NUMBER         31

const char *svn_string_revision      = "31"; // line 47

#endif //_VERSION_H_

Usage:

main.c:

#include "version.h"
// I do not use svn_string_revision here.
// I only use SVN_REVISION_NUMBER
#pragma config IDLOC3=SVN_REVISION_NUMBER

otherfile.c:

#include "version.h"
// still no usage of svn_string_revision, only this:
EUSART_Write(SVN_REVISION_NUMBER);

So far this is descriptive and clear. I assume the problem is that the const char string is defined in a header file, which gets included in more than one source code file. So the compiler sees more than one "svn_string_revision" variable and treats it as redeclaration. But normally the value should be always the same. My version.h file is an auto generated file which gets regenerated prior to every build.

Has somebody encountered this before, and how can I handle that? The clean approach would be to use a version.h file complemented with a version.c, where the header declares

extern const char *svn_string_revision;

and the source

const char *svn_string_revision = "31";

But this would require me to rewrite the automated code generation, which I would like to avoid.

Long story short, my questions are:

  • Is my understanding of the warning correct?
  • How can I avoid those warnings gracefully, given that I don't want to split up version.h into a .c and .h file

Solution

  • First solution :

    static const char *svn_string_revision = "31";
    

    The static will make the variable local to each C file, so no conflict can occur. Since it is a read only constant it should be fine. However, this means there will be many copies of the variable in the program. A good compiler can optimize this, but in my experience, I'm not sure XC8 will do that.

    Second solution, probably better :

    #define SVN_REVISION_NUMBER         31
    #define STRINGIFY(s) #s
    extern const char *svn_string_revision;
    
    // in version.c
    const char *svn_string_revision = STRINGIFY(SVN_REVISION_NUMBER);
    

    Or just :

    #define SVN_REVISION_NUMBER         31
    #define VERSION_STRING "31"
    extern const char *svn_string_revision;
    
    // in version.c
    const char *svn_string_revision = VERSION_STRING;
    

    You could also just remove svn_string_revision and use VERSION_STRING instead, but you should check before that XC8 doesn't create many copies of the string.