Linker gives error “undefined symbol” for integral static const members used in certain contexts [duplicate]

拜拜、爱过 提交于 2019-12-23 21:13:12

问题


Possible Duplicate:
C++ - defining static const integer members in class definition

Note: There are several extant questions re similar issues, but I have reviewed many of them and cannot find an answer that explains this behavior:

Say I have code such as the following (in a header file)

class Foo {
    static const int TEST = 33;

    public:
    void willItWork(void) {
        printf("%d", std::max(TEST, 75));  // embedded platform, no streams
    }
};

int main(void) {
    Foo tester;
    tester.willItWork();
}

This will compile, but it will not link. I get the linker error

Error: L6218E: Undefined symbol Foo::TEST (referred from foo.o).

It only seems like passing the value to outside functions causes problems. Using TEST in ordinary expressions or functions within the class works fine. If I instead write willItWork() as

void willItWork(void) {
    int diff = TEST - 23;
    printf("%d", diff);
}

there is no error.

I found another question that referenced the C++ standard regarding this (Section 9.4.2):

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a const-initializer which shall be an integral constant expression.

Since what I have done seems to be "within the rules," can anyone think of any possible explanation for this odd behavior?

I tried similar code on ideone and had no issue (however, I can not mimic the exact structure, i.e. with header files, there). Does this mean the linker I am using doesn't quite conform to the standard here?

Any insight is greatly appreciated. I can always provide more information, too.


回答1:


If the compiler feels it needs the address of the static member variable, e.g., when binding the variable to a reference at some point, it will create a corresponding undefined symbol and you will have to define the member:

int const foo::TEST;

(in one translation unit). If the compiler only ever accesses a the value you can get away with not defining the object. Unless you need the type to be an int, you can use an enum instead and avoid the need for defining the member:

enum { TEST = 33 };

The term in the standard to look for is odr-used if I recall correctly.




回答2:


std::max takes its arguments by reference, not by value. Binding a reference to your static const requires an actual object, not just the value.



来源:https://stackoverflow.com/questions/13390376/linker-gives-error-undefined-symbol-for-integral-static-const-members-used-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!