VS2012 不编译此代码,但 G++、clang 和 ICC 都接受它而无需诊断
VS2012 doesn't compile this code, but G++, clang, and ICC all accept it without a diagnostic
基于这个答案,我为C++中的常量树结构编写了以下代码:
#include <tuple>
struct T
{
T(const char* n, const T& n1, const T& n2, const T& n3, const T& n4):
name(n), nodes(n1, n2, n3, n4) {}
const char* name;
std::tuple<const T&, const T&, const T&, const T&> nodes;
};
T n(0, n, n, n, n);
GCC(4.5.3和最新版本)、ICC(17)和CLang(3.5和最新版)都编译了这段代码(CLang 3.5会发出-Wuninitialized
警告,但这没关系,因为n
是一个占位符,其值无关紧要)。
然而,MSVC 11(VS2012)在n
:的定义上抛出了C2065错误
test6.cpp(12):错误C2065:"n":未声明的标识符
给出什么?MSVC是否拒绝有效代码?我是不是在UB的土地上,恶魔从我的鼻子里飞了出来?如果这是无效的,有人能告诉我标准中的什么使它无效和/或为什么GCC、Clang和ICC都接受它吗?
将其缩短为一个简单的
unsigned char x(x);
并在上在线测试http://webcompiler.cloudapp.net/显示当前版本的微软编译器仍然拒绝它。
这是一个编译器错误。引用标准(N4140,大致为C++14,但规则与早期标准相同):
3.3.2申报点[basic.scope.pdecl]
1名称的声明点紧接在其完整声明符(第8条)之后,且在其初始值设定项(如果有)之前,除非下文另有说明。示例:
unsigned char x = 12; { unsigned char x = x; }
这里,第二个
x
用它自己的(不确定的)值初始化结束示例]
= x;
和(x);
在语法上都是初始值设定项,在(x);
语法中,变量x
不知何故还不在作用域中。
Visual Studio的编译器确实接受= x;
语法。
但是,由于它只影响在初始化中使用变量的代码,因此更好地重新处理代码只会完全避免问题。
相关文章:
- 当简单捕获中的标识符显示为参数的声明符 ID 时,没有编译器诊断
- 如何使用CAPL的诊断功能获取CAN传输的数据(256字节)?
- 在 std::index_sequence 中没有诊断包膨胀
- #pragma(*诊断)当将Clang分析器与GCC编译器混合时
- constexpr 函数的常量引用参数:gcc/msvc vs clang/icc
- 为什么 icc 为简单的主电源生成奇怪的组件?
- GCC 编译器是否应该对涉及 [[fallthrough]] 属性的格式错误的C++代码进行诊断?
- JPG-如何从ICC配置文件部分APP2读取/提取数据
- 对clang、gcc和icc中开关枚举类返回的处理一致
- 使用类/函数模板组合进行意外诊断
- 设置诊断:插入符号来自 CMakeLists.txt
- 为什么在类似问题上通过叮当进行不同的诊断?
- 忽略由第三方标头引起的 [叮当声诊断错误] 叮当声整洁
- 叮叮当当的'range-loop-analysis'诊断是关于什么的?
- ICC 中的 -O3 会弄乱内联函数,使用 -O1 或 -O2 或相应的手动组装
- ICC 中的 -O2 搞砸了汇编程序,ICC 中的 -O1 和 GCC / Clang 中的所有优化都很好
- 如何诊断保存和加载位向量(std::vector)的奇怪行为<bool>?
- 函数指针的模板参数推导(g++ & ICC vs Clang++ & VC++)
- ICC:包括OMP.H需要BytesWap.H
- VS2012 不编译此代码,但 G++、clang 和 ICC 都接受它而无需诊断