VS2012 不编译此代码,但 G++、clang 和 ICC 都接受它而无需诊断

VS2012 doesn't compile this code, but G++, clang, and ICC all accept it without a diagnostic

本文关键字:ICC 诊断 clang 编译 代码 G++ VS2012      更新时间:2023-10-16

基于这个答案,我为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;语法。

但是,由于它只影响在初始化中使用变量的代码,因此更好地重新处理代码只会完全避免问题。