Search code examples
c++compiler-errorsxilinxvivado

Why does Release not build though Debug goes, but only for one of the projects using the same source file?


The C++ compiler for Xilinx SDK, compiling code for a Zynq SoC (an ARM core), complains about an uninitialized variable, but only in the Release build, and only for one project. Debug is fine, and both Debug and Release builds are fine for another project linking to the same source file newthing.cpp. There are no project-dependent #ifdefs that I can see. As far as I can tell, all the build settings are the same, except of course debug info and optimization are different between Release and Debug, but not different between projects. One of us suspects a bug in Xilinx tools, but possibly there's a subtle difference somewhere other than the obvious places such as makefiles or Build Settings in the IDE.

The trouble is in code like this (in newthing.cpp):

Result R;
GetSomeResult(7, R);
PushData(R.blip);     <== compiler whines: using uninitialized var

where the newthing.h header defines

struct Result
{
    int blip;
    int bloop;
};

and the Result struct, defined elsewhere in newthing.cpp, is filled in like this:

int GetSomeResult(int n, Result &res)
{
   res.blip = n + 100;
   res.bloop = 50;
   return n;
}

Note that I'm ignoring the return value from GetSomeResult, but I doubt that's relevant.


Solution

  • It's a false negative.

    If you can, just zero-initialise the structure before you pass it to GetSomeResult:

    Result R = {};
    GetSomeResult(7, R);
    PushData(R.blip);
    

    If that's not feasible (in very rare cases it may be too slow/wasteful), you'll have to use your build system or a #pragma to turn off that warning/error for this translation unit.

    You may also wish to try with a newer version of your compiler, if possible.

    Of course, your code would be more idiomatic and not susceptible to this problem if you dropped the C-like approach and instead wrote:

    Result GetSomeResult(const int n)
    {
       Result res;
       res.blip = n + 100;
       res.bloop = 50;
       return res;
    }
    
    // const Result R = GetSomeResult(7);
    // PushData(R.blip);