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.
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?
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