Is it legal C++ to pass the address of a static const int with no definition to a template?

本秂侑毒 提交于 2019-12-19 10:25:57

问题


I'm having trouble deciding whether not this code should compile or if just both compilers I tried have a bug (GCC 4.2 and Sun Studio 12). In general, if you have a static class member you declare in a header file you are required to define it in some source file. However, an exception is made in the standard for static const integrals. For example, this is allowed:

#include <iostream>

struct A {
    static const int x = 42;
};

With no need to add a definition of x outside the class body somewhere. I'm trying to do the same thing, but I also take the address of x and pass it to a template. This results in a linker error complaining about a lack of definition. The below example doesn't link (missing a definition for A::x) even when it's all in the same source file:

#include <iostream>

template<const int* y>
struct B {
    static void foo() { std::cout << "y: " << y << std::endl; }
};

struct A {
    static const int x = 42;
    typedef B<&x> fooness;
};

int main()
{
    std::cout << A::x << std::endl;
    A::fooness::foo();
}

Which is bizarre since it works as long as I don't pass the address to a template. Is this a bug or somehow technically standards compliant?

Edit: I should point out that &A::x is not a runtime value. Memory is set aside for statically allocated variables at compile time.


回答1:


To be a well formed program you stil have to have the defintion of the static variable (without an initializer in this case) if it actually gets used, and taking the address counts as a use:

  • C++2003 Standard: 9.4.2 Static data members Paragraph 4 (bold added)

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer




回答2:


You are trying to pass a runtime value to a template, that's not possible. The only allowed template parameters are types (class/typename) or integral constant values (int/bool/etc).




回答3:


Interesting, it compiled fine for me on VS 2008. I kind of assumed that the error came from the typedef because at compile time when it tries to compile 'B' with &x as the template type it doesn't then know where the address of x will be. Still... it compiles and gives a reasonable output.




回答4:


I could see how one might expect this to compile anyway.

The address of a static const isn't really a runtime value and can be fully resolved at link time.



来源:https://stackoverflow.com/questions/1257267/is-it-legal-c-to-pass-the-address-of-a-static-const-int-with-no-definition-to

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