Reputation: 2635
I've got the following code that has a template function that is not called at any point:
#include <exception>
class MyException : public std::exception {
protected:
MyException( const char* name, const char* reason = nullptr ){
}
};
template <typename T>
void doSomething( T& temp ){
throw MyException( "reason" );
}
int main(int argc, char** argv){
}
When using g++, the code compiles just fine, however using clang the compilation fails with the following error:
$ clang++ -std=c++11 -o clang-test test.cpp
test.cpp:11:8: error: calling a protected constructor of class 'MyException'
throw MyException( "reason" );
^
test.cpp:5:2: note: declared protected here
MyException( const char* name, const char* reason = nullptr ){
^
1 error generated.
If I call the function doSomething
, g++ will then fail with a similar error:
test.cpp:11:8: error: ‘MyException::MyException(const char*, const char*)’ is protected within this context
So it seems that g++ is not bothering to parse the template function if it is not called, while clang is. Are both g++ and clang valid in this case(e.g. it is compiler-specific/undefined), or is one of these compilers not aligned with the specification?
Upvotes: 2
Views: 540
Reputation: 141544
C++17 [temp.res]/8 says:
The program is ill-formed, no diagnostic required, if:
- (8.1) no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
- [...]
- (8.3) a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter
- [...]
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
I'm never too sure about template instantiation stuff, but I think your program falls foul of both 8.1 and 8.3. Every instantiation of the template will be ill-formed due to the access check failing, and there are no valid specializations (i.e. no T
which makes it valid).
So the program is ill-formed NDR and therefore neither compiler is bugged.
Upvotes: 1