gcc错误的是不能诊断非类型模板参数中的缩小转换吗?

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获得的所有错误都是"超出最大模板实例化深度".

Ser*_* K. 2

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)

  • 这是一个有用的观点(+1),但我不认为这是一个答案。§ 5.19/3(引用)*允许*转换后的常量表达式*隐式转换*为目标类型,但仍然明确禁止缩小转换。`-Wsign-conversion` 提供了标准允许的转换的有用诊断。因此,即使使用“-pedantic”也不会激活,但即使使用“-pedantic”,也无法诊断标准禁止的缩小转换。此 GCC 警告在 C 中也很常见,并且比 C++11 中禁止缩小转换的时间要早​​得多。 (3认同)
  • 我也尝试过“-迂腐”,但很失望。对我来说这看起来像是一个编译器错误。 (2认同)