我在C ++代码中使用以下内容:
int a = 0, b = a;
我想知道这种行为是否可靠并且定义正确(名称声明的从左到右顺序),并且我的代码不会与其他编译器一起出现未声明名称错误的错误。>
如果不可靠,我会破坏声明:
int a = 0;
int b = a;
谢谢。
答案 0 :(得分:4)
我相信答案是否定的。
它受core active issue 1342的约束:
目前尚不清楚,在现有规范中,有什么要求(如果有的话)要求在单个声明中对多个init声明符的初始化应以声明顺序进行。
我们在[dcl.decl]p3中有一个非规范性注释,内容为:
... [注:通常带有多个声明符的声明 相当于相应的声明序列,每个声明都有一个 单个声明符。那是
T D1, D2, ... Dn;
通常等同于
T D1; T D2; ... T Dn;
...
但是它是非规范性的,它根本不涉及初始化情况,据我所知,规范性措辞没有说同一件事。
尽管该标准确实涵盖了[basic.scope.pdecl]p1中的名称范围,但其内容为:
名称的声明要在名称完成后立即进行 声明符,并在其初始值设定项(如果有)之前,以下所述除外。 [示例:
unsigned char x = 12; { unsigned char x = x; }
这里第二个x用其自己的(不确定的)值初始化。 —示例example]
答案 1 :(得分:3)
您想问这个问题的事实表明该样式不是很好。即使单行版本几乎可以保证 †正常工作,但我还是会采用两行方法,以使读者更加清晰。
†我最初说是可以保证的,但我会退后一步。在查看了规范的相关部分之后,我可以看到语言律师将如何抱怨没有明确声明此保证。 (正如Shafik Yaghmour指出的那样,core active issue 1342指出了缺乏明确的保证,尽管措辞表明应该提供这种保证。)
但是,由于“ Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.”的强烈暗示,我将仅退回到“几乎保证”。也就是说,对int a = 0, b = a;
的分析分为两部分:一部分将名为a
的变量初始化为0
,另一部分将名为b
的变量初始化为值a
中的。如果您确实将这些部分分开,那么第一部分将必须在第二部分开始之前完成(否则它们就好像每个部分本身都不在声明中一样),因此a
的值为{{ 0
之前的1}}。我接受这对于语言律师来说可能还不够明确,但是如果存在某行的编译器无法按预期运行的情况,那么对于编译器的错误报告就应该足够了。
我很抱歉没有更早查找规格。当我最初回答时,“ language-lawyer”标签不存在。
答案 2 :(得分:0)
定义多个用逗号分隔的变量的声明语句与按相同顺序定义单个变量的多个声明语句完全等效,因为变量的作用域仅在其名称之后开始,但是(至少)两个例外:
1)当变量声明隐藏具有相同名称的类型时,如下所示:
struct S {};
S S, T;
不同于
struct S {};
S S;
S T; //error: S is a variable name
但是
struct S {};
S S, T{S};
等同于
struct S{};
S S;
struct S T{S};
2)使用 auto
和 decltype(auto)
说明符时:
auto i{0}, j{i}, k{2.0}; // error: deduction for auto fails, double or int?
不同于
auto i{0};
auto j{i};
auto k{2.0};
无论如何,评估顺序始终是从左到右。