C++ 声明顺序(在多变量声明行中)
C++ Order of Declaration (in Multi-variable Declaration Line)
我在我的 C++ 代码中使用了以下内容:
int a = 0, b = a;
我想知道这种行为是否可靠且定义明确(名称声明从左到右的顺序),并且我的代码不会因其他未声明名称[=21=的编译器而中断] 错误。
如果不可靠,我会打破这个说法:
int a = 0;
int b = a;
谢谢。
你想问这个问题说明风格不是很好。尽管单行版本 几乎可以保证† 可以工作,但我仍然会使用两行方法,以便更清晰地显示人类读者。
† 我最初说这是有保证的,但我会退后一步。在查看规范的相关部分后,我可以看到语言律师会如何抱怨没有明确说明此保证。 (正如 Shafik Yaghmour 指出的那样,core active issue 1342 注意到缺乏明确的保证,尽管措辞表明应该存在这样的保证。)
不过,我只会退回到 "almost guaranteed",因为“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
在 b
初始化之前。我承认这对于语言律师来说可能不够明确,但如果存在该行无法按预期工作的编译器,那么对于编译器的错误报告来说应该足够好了。
很抱歉没有早点查看规范。我最初回答时 "language-lawyer" 标签不存在。
我认为答案是否定的。
它受制于 core active issue 1342 说:
It is not clear what, if anything, in the existing specification requires that the initialization of multiple init-declarators within a single declaration be performed in declaration order.
我们在 [dcl.decl]p3 中有非规范性注释,它说:
...[ Note: A declaration with several declarators is usually
equivalent to the corresponding sequence of declarations each with a
single declarator. That is
T D1, D2, ... Dn;
is usually equivalent to
T D1; T D2; ... T Dn;
...
但它是非规范的,它根本不涵盖初始化情况,据我所知,没有规范的措辞说同样的话。
尽管该标准确实涵盖了 [basic.scope.pdecl]p1 中的名称范围,其中表示:
The point of declaration for a name is immediately after its complete
declarator and before its initializer (if any), except as noted below.
[ Example:
unsigned char x = 12;
{ unsigned char x = x; }
Here the second x is initialized with its own (indeterminate) value.
— end example ]
用逗号分隔定义多个变量的声明语句完全等同于以相同顺序定义单个变量的多个声明语句,因为变量的范围从它的名称之后开始,但有(至少) 两个例外:
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};
无论如何,评估顺序总是从左到右。
我在我的 C++ 代码中使用了以下内容:
int a = 0, b = a;
我想知道这种行为是否可靠且定义明确(名称声明从左到右的顺序),并且我的代码不会因其他未声明名称[=21=的编译器而中断] 错误。
如果不可靠,我会打破这个说法:
int a = 0;
int b = a;
谢谢。
你想问这个问题说明风格不是很好。尽管单行版本 几乎可以保证† 可以工作,但我仍然会使用两行方法,以便更清晰地显示人类读者。
† 我最初说这是有保证的,但我会退后一步。在查看规范的相关部分后,我可以看到语言律师会如何抱怨没有明确说明此保证。 (正如 Shafik Yaghmour 指出的那样,core active issue 1342 注意到缺乏明确的保证,尽管措辞表明应该存在这样的保证。)
不过,我只会退回到 "almost guaranteed",因为“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
在 b
初始化之前。我承认这对于语言律师来说可能不够明确,但如果存在该行无法按预期工作的编译器,那么对于编译器的错误报告来说应该足够好了。
很抱歉没有早点查看规范。我最初回答时 "language-lawyer" 标签不存在。
我认为答案是否定的。
它受制于 core active issue 1342 说:
It is not clear what, if anything, in the existing specification requires that the initialization of multiple init-declarators within a single declaration be performed in declaration order.
我们在 [dcl.decl]p3 中有非规范性注释,它说:
...[ Note: A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is
T D1, D2, ... Dn;
is usually equivalent to
T D1; T D2; ... T Dn;
...
但它是非规范的,它根本不涵盖初始化情况,据我所知,没有规范的措辞说同样的话。
尽管该标准确实涵盖了 [basic.scope.pdecl]p1 中的名称范围,其中表示:
The point of declaration for a name is immediately after its complete declarator and before its initializer (if any), except as noted below. [ Example:
unsigned char x = 12; { unsigned char x = x; }
Here the second x is initialized with its own (indeterminate) value. — end example ]
用逗号分隔定义多个变量的声明语句完全等同于以相同顺序定义单个变量的多个声明语句,因为变量的范围从它的名称之后开始,但有(至少) 两个例外:
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};
无论如何,评估顺序总是从左到右。