Mik*_*han 11 type-conversion narrowing non-type c++11
以下程序使用gcc 4.8.1编译时没有错误或警告
-Wall -std=c++11:
template<unsigned N>
struct A{};
int main(){
A<1-2> a;
(void)a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用相同选项的clang 3.3会出现此错误:
错误:非类型模板参数的计算结果为-1,不能缩小为'unsigned int'类型[-Wc ++ 11-narrowing]
根据这个问题,看起来gcc的现行政策只是为了缩小标准指示错误的转换,以及clang给出指示错误的警告.但在这种情况下,gcc甚至没有发出警告.
标准第8.5.4/7节(在该问题中再现)中缩小转换错误的例子都没有涵盖非类型模板参数缩小转换的情况,但是§14.3.2/ 5标准说:
对于积分或枚举类型的非类型模板参数,将应用转换常量表达式(5.19)中允许的转换.
并且§5.19/ 3说:
T类型的转换常量表达式是一个文字常量表达式,隐式转换为类型T,其中隐式转换(如果有)在文字常量表达式中是允许的,而隐式转换序列仅包含用户定义的转换,lvalue-to- 除缩小转化次数之外的右值转换(4.1),整数促销(4.5)和积分转换(4.7)(8.5.4)
(我的重点).
在我看来,这意味着即使按照自己的标准,gcc也是错误的,在这种情况下根本没有诊断出变窄的转换.我读得对吗?是否存在基于标准的反驳论点?
我更多的感觉只是好奇心问这个问题.在递归TMP设置中,clang在这种情况下的错误诊断将查明无符号非类型模板参数通过0的错误,而从gcc获得的所有错误都是"超出最大模板实例化深度".
GCC 并不像 Clang 那样迂腐,但是,它仍然可以检测到此类错误:
gcc -Wsign-conversion 1.cpp
1.cpp: In function 'int main()':
1.cpp:5:10: warning: negative integer implicitly converted to unsigned type [-Wsign-conversion]
A<1-2> a;
^
Run Code Online (Sandbox Code Playgroud)
-Wall实际上并没有打开所有可能的检查。阅读此页面以获取更多示例:http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
我在用着gcc.EXE (GCC) 4.8.0 20130203 (experimental)