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