以下程序使用gcc 4.8.1编译时没有错误或警告,
-Wall -std=c++11
:
template<unsigned N>
struct A{};
int main(){
A<1-2> a;
(void)a;
return 0;
}
带有相同选项的clang 3.3会出现此错误:
错误:非类型模板参数的计算结果为-1,不能缩小为'unsigned int'类型[-Wc ++ 11-narrowing]
根据this question,它看起来如此 像gcc目前的政策只是为了缩小转换的警告 标准表示错误,并且clang给出指示的错误。 但在这种情况下,gcc甚至没有发出警告。
没有缩小转换错误的示例 §8.5.4/ 7的标准(转载于that question) 涵盖了非类型模板参数缩小转换的情况, 但根据§14.3.2/ 5标准说:
对于整数或枚举类型的非类型模板参数,con中允许的转换 应用了垂直常量表达式(5.19)。
并且§5.19/ 3说:
T类型的转换常量表达式是一个文字常量表达式,隐式转换为T类型, 其中隐式转换(如果有)在文字常量表达式和隐式转换中是允许的 序列仅包含用户定义的转换,左值到右值转换(4.1),整数促销(4.5), 和积分转换(4.7),而不是缩小转化次数(8.5.4)
(我的重点)。
在我看来,这意味着即使按照自己的标准,gcc也有过错,根本没有诊断出来 在这种情况下缩小转换率。我读得对吗?有没有 基于标准的反驳论点?
我问这个问题的感觉只是好奇心。在一个 递归TMP设置,在这种情况下clang的错误诊断将精确定位a 无符号非类型模板参数落入的错误 通过0,而你从gcc获得的是“超出最大模板实例化深度”。
答案 0 :(得分:2)
海湾合作委员会并不像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;
^
-Wall
实际上并未启用所有可能的检查。
阅读此页面以获取更多示例:http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
我正在使用gcc.EXE (GCC) 4.8.0 20130203 (experimental)