C++ Order of Declaration (in Multi-variable Declaration Line)

拟墨画扇 提交于 2020-01-12 15:18:10

问题


I use the following in my C++ code:

int a = 0, b = a;

I would like to know if this behaviour is reliable and well defined (left to right order of name declaration) and that my code will not break with other compilers with an undeclared name error.

If not reliable, I would break the statement:

int a = 0; 
int b = a;

Thank you.


回答1:


I believe the answer is no.

It is subject to core active issue 1342 which says:

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.

We have non-normative note in [dcl.decl]p3 which says:

...[ 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;

...

but it is non-normative and it does not cover the initialization case at all and as far as I can tell no normative wording says the same thing.

Although the standard does cover the scope of names in [basic.scope.pdecl]p1 which says:

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  ]




回答2:


The fact that you thought to ask this question suggests that the style is not great. Even though the one-line version is almost guaranteed to work, I would still go with the two-line approach for the greater clarity to human readers.


I initially said it was guaranteed, but I will step back from that. After reviewing the relevant portion of the spec, I can see how language lawyers would complain that this guarantee is not explicitly stated. (As Shafik Yaghmour points out, core active issue 1342 notes the lack of an explicit guarantee, albeit with phrasing that suggests that such a guarantee should be present.)

I will step back only to "almost guaranteed", though, as it is strongly implied by "Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself.". That is, the analysis of int a = 0, b = a; has two parts: one where a variable named a is initialized to 0, and one where a variable named b is initialized to the value of a. If you are truly keeping these parts separate, then the first part would have to finish before the second part begins (otherwise they are not as if each was in a declaration by itself), so a would have the value 0 before b is initialized. I accept that this might be not definite enough for the language lawyers, but it should be good enough for a compiler's bug report if there is a compiler for which that line does not work as intended.

My apologies for not looking up the spec earlier. The "language-lawyer" tag was not present when I initially answered.




回答3:


A declaration statement that defines multiple variables separated by comma is exactly equivalent to multiple declaration statements that defines a single variable in the same order because the scope of a variable begins just after it's name, but there are (at least) two exceptions:

1) When a variable declaration hides a type with the same name, as in:

struct S {};
S S, T;

Is different from

struct S {};
S S;
S T; //error: S is a variable name

But

struct S {};
S S, T{S};

Is equivalent to

struct S{};
S S;
struct S T{S};

2) When using the auto and decltype(auto) specifiers:

auto i{0}, j{i}, k{2.0}; // error: deduction for auto fails, double or int?

Is different from

auto i{0};
auto j{i};
auto k{2.0};

In any case, evaluation order is always from left to right.



来源:https://stackoverflow.com/questions/53698162/c-order-of-declaration-in-multi-variable-declaration-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!