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.

Compiler/TMS320C28346: Linker error #10056 initialization guard variable redefined

Part Number: TMS320C28346

Tool/software: TI C/C++ Compiler

I have an inline function in a header:

template <unsigned Class, unsigned Index>
inline bool hasFeatureBuffered()
{
    static bool const featureAvailable =
        hasFeature(getFeatureClass(Class), Index);
    return featureAvailable;
}

I get a bunch of errors:
<Linking>
error #10056: symbol "initialization guard variable for bool
   hasFeatureBuffered<N1, N2>() [with N1=(unsigned int)8, N2=(unsigned
   int)52]::featureAvailable" redefined: first defined in
   "./ServoLibrary/service/sensor/ProxiedAdConverter.obj"; redefined in
   "./application/InverterSettings.obj"
error #10056: symbol "initialization guard variable for bool
   hasFeatureBuffered<N1, N2>() [with N1=(unsigned int)8, N2=(unsigned
   int)45]::featureAvailable" redefined: first defined in
   "./ServoLibrary/service/timing/timing_unit/CTimingUnit.obj"; redefined in
   "./platform/servo/common/application/tasksIsd510.obj"

I'm stuck on C2000 6.1.0 for now.

It looks to me like the linker fails to merge the featureAvailable instances from different translation units. My understanding of the language is that the inline keyword takes the ODR out of effect and the linker has to merge these instances.

A solution (viable here), because the hasFeature() call has no side effects, is to make it a static inline. Declaring a static function in a header is a vomit inducing prospect though and the waste of memory is at least distasteful.

Is there an elegant way out of this conundrum?

  • One afterthought, I was expecting to get warning #1369 when writing that code.
  • Dominic Fandrey said:
    Is there an elegant way out of this conundrum?

    Unfortunately, no.  Your issue is discussed in the article C++ Inlining Issues.  Note that, since you build for C28x, this article does apply to you.  It does not apply to users of ARM, C6000, MSP430, or PRU devices.

    The workaround given for the template case presumes the problem static variable is inside a member function of a template class.  The solution, in that case, is to move the static variable out to the class, where it is a static data member of the class.  No solution is given for a non-class template function, which is what you show.  I presume what you show is a cut down of the actual problem, and there really is a template class which can hold a static data member.

    Thanks and regards,

    -George

  • Dominic Fandrey said:
    One afterthought, I was expecting to get warning #1369 when writing that code.

    For those following along, warning #1369 occurs when building a C++ source file, before linking.  It looks like ...

    "hdr.h", line 4: warning #1369-D: static local variables of extern inline function are not resolved to single copy. Not ANSI C++ Compliant
              detected during instantiation of "bool hasFeatureBuffered<Class,Index>() [with Class=8U, Index=32U]" at line 5 of "t2.cpp"

    When I construct a toy test case based on your example, I get this warning.  So I don't know why you don't see it.

    Thanks and regards,

    -George

  • There currently isn't a class. I could wrap one around it, but I think static class members are constructed during global object initialisation, which must not happen, because the information retrieved is not yet available.

    The static must be initialised during first call.

    For now I'll go with declaring the function static, so I'll have one value copy per translation unit, which right now seems to be the least of bad choices.