static_assert fails compilation even though template function is called nowhere

醉酒当歌 提交于 2019-11-26 05:29:15

问题


I use g++ 4.6.3, (currently default package for ubuntu 12.04) with the flag c++0x, and I stumble across this:

template <typename T>
inline T getValue(AnObject&)
{
    static_assert(false , \"this function has to be implemented for desired type\");
}

with the compilation error:

static_assertion failed \"this function has to be implemented for the desired type\"

even though I don\'t call this function anywhere yet.

Is it a g++ bug ? Shouldn\'t this function be instanciated only if it is called somewhere in the code.


回答1:


That's because the condition does not depend in any way on the template parameters. Therefore, the compiler can evaluate it even before instantiating that template, and produces the associated compilation error message if it the evaluation yields false.

In other words, this is not a bug. Although many things can only be checked once a template is instantiated, there are other validity checks that a compiler can perform even before. This is why C++ has a two-phase name lookup, for instance. The compiler is just trying to help you finding errors that are 100% likely to occur.




回答2:


The standard says in [temp.res]/8

No diagnostic shall be issued for a template definition for which a valid specialization can be generated. If no valid specialization can be generated for a template definition, and that template is not instantiated, the template definition is ill-formed, no diagnostic required. ... [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. — end note ]

There is no possible way to instantiate your function template that will compile, so the template definition is ill-formed and so the compiler is allowed (but not required) to reject it even if it isn't instantiated.

You could make it work like this:

template<typename T>
struct foobar : std::false_type
{ };

template <typename T>
inline T getValue(AnObject&)
{
    static_assert( foobar<T>::value , "this function has to be implemented for desired type");
}

Now the compiler cannot reject the function template immediately, because until it is instantiated it doesn't know whether there will be a specialization of foobar that has value == true. When instantiated the relevant specialization of foobar<T> will be instantiated and the static assertion will still fail, as desired.




回答3:


This is really a comment, but requiring a code example.

The holy standard's wording for static_assert does not limit its effect to instantiated code.

However, the code

template <typename T>
inline T getValue(int&)
{
    typedef char blah[-1];  // Common C++03 static assert, no special semantics.
}

int main()
{}

also fails to compile with MinGW g++ 4.7.2, which accentuates the question.

I think the answer is that g++ is right, and that Visual C++ 11.0, which does not produce a compilation error for this, is wrong, but I'd be hard pressed to provide the relevant analysis in terms of the Holy Standard's verses.

A practical consequence of the compiler difference is that presently you can not rely on the behavior.



来源:https://stackoverflow.com/questions/14637356/static-assert-fails-compilation-even-though-template-function-is-called-nowhere

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