What is the meaning of "each undeclared identifier is reported only once for each function it appears in error"?

huangapple go评论57阅读模式
英文:

What is the meaning of "each undeclared identifier is reported only once for each function it appears in error"?

问题

我知道相同数据类型的多个变量可以在一条语句中声明如下:

int x, y, z;

我尝试在一条语句中声明和定义多个属于相同数据类型的变量,如下所示:

#include <stdio.h>

int main() {
  int x = y = z = 50;
  printf("%d", x + y + z);
  return 0;
}

当我尝试编译上述代码时,我收到以下错误消息:

prog.c: In function ‘main’:
prog.c:4:11: error: ‘y’ undeclared (first use in this function)
    4 |   int x = y = z = 50;
      |           ^
prog.c:4:11: note: each undeclared identifier is reported only once for each function it appears in
prog.c:4:15: error: ‘z’ undeclared (first use in this function)
    4 |   int x = y = z = 50;
      |               ^

我不明白为什么相同数据类型的多个变量不能在单个语句中初始化为相同的值,而声明多个相同数据类型的变量是可能的。

我也不明白注释中的实际含义:“each undeclared identifier is reported only once for each function it appears in.” 为什么会出现这个提示?

尽管如此,当我尝试下面的代码,其中我分别创建了两个语句来声明和定义变量时,一切都顺利进行。为什么呢?

#include <stdio.h>

int main() {
  int x, y, z;
  x = y = z = 50;
  printf("%d", x + y + z);
  return 0;
}

并且得到了以下预期的输出:

150
英文:

I know that multiple variables belonging to same data type can be declared in one statement as below:

int x, y, z;

I tried to declare and define multiple variables belonging to same data-type in one statement as below :

#include &lt;stdio.h&gt;

int main() {
  int x = y = z = 50;
  printf(&quot;%d&quot;, x + y + z);
  return 0;
}

When I tried to compile above code I got following errors:

prog.c: In function ‘main’:
prog.c:4:11: error: ‘y’ undeclared (first use in this function)
    4 |   int x = y = z = 50;
      |           ^
prog.c:4:11: note: each undeclared identifier is reported only once for each function it appears in
prog.c:4:15: error: ‘z’ undeclared (first use in this function)
    4 |   int x = y = z = 50;
      |               ^

I don't understand why multiple variables belonging to same data type cannot be initialized to the same value in a single statement, whereas it is possible to declare multiple variables belonging to same data type.

I also don't understand the actual meaning of the note "each undeclared identifier is reported only once for each function it appears in." Why is it appearing?

Though, when I tried below code where I created two statements for variable declaration and definition separately everything worked smoothly. Why so?

#include &lt;stdio.h&gt;

int main() {
  int x, y, z;
  x = y = z = 50;
  printf(&quot;%d&quot;, x + y + z);
  return 0;
}

And got expected below output:

150

答案1

得分: 3

int x = y = z = 50;

赋值运算符 = 具有从右到左的结合性1。上述语句被解析为:

int x = (y = (z = 50));

它首先尝试将 50 分配给 L 值 z,然后将 z 的结果转换为 y 的类型并将其分配给 L 值 y,然后使用将 y 的结果转换为 x 的类型来初始化 L 值 x。但在初始化之前,yz 从未被声明,因此它生成了一个警告。

如果要解析为以下表达式:

(((int x = y) = z) = 50);

将会引发错误,因为表达式 x = y 不是一个 L 值,即它具有 R 值但没有 L 值来存储 z 的结果。

> 我不明白为什么属于相同数据类型的多个变量不能在单个语句中初始化为相同的值,而可以声明属于相同数据类型的多个变量。

实际上,您可以这样做,但只有在先声明它们的情况下才能这样做。在这种情况下,您在初始化之前没有声明 yz

您要寻找的是:

1) int x = 50, y = 50, z = 50;

   /* 或者 */

2) int x, y, z; 
 
   x = y = z = 50;

   /* 或者 */

3) int x = 50;
   int y = 50;
   int z = 50;

   /* 或者 */

4) int x, y, z = x = y = 50; /* 这太疯狂了。 */

我发现每行声明一个变量(第三种方法)使代码更清晰,防止在声明指针时犯愚蠢的错误。

> 我也不明白注释的实际含义是什么:“每个未声明的标识符仅在出现在每个函数中的第一次报告。” 为什么它会出现?

这意味着编译器只会报告在给定函数中未声明变量的第一次实例。例如,如果您有:

int x = y = z = 50;  /* 编译器只报告此实例 */

z = 403;

编译器只会报告 z 第一次出现的情况。

脚注:

1

在同一单元格中的运算符(可能有多行运算符列表在同一单元格中)以给定的方向具有相同的优先级。例如,表达式 a=b=c 被解析为 a=(b=c),而不是 (a=b)=c,因为它具有从右到左的结合性。

英文:
int x = y = z = 50;

The assignment = operator has right-to-left associativity1. The above statement is parsed as:

int x = (y = (z = 50));

which first tries to assign 50 to the L-value z, then assigns the result of z converted to the type of y to the L-value y, and then initializes the L-value x with the result of y converted to the type of x. But y and z were never declared before, so it generated a warning.

The alternative expression, if it was to be parsed as such:

(((int x = y) = z) = 50);

would raise an error because the expression x = y is not an L-value, i.e. it has an R-value but not an L-value where to store the result of z.


> I don't understand why multiple variables belonging to same data type
> cannot be initialized to the same value in a single statement, whereas
> it is possible to declare multiple variables belonging to same data
> type.

Actually you can, but only if you declare them first. In this case, you didn't declare y and z before initializing them.

What you're looking for is:

1) int x = 50, y = 50, z = 50;

   /* OR */

2) int x, y, z; 
 
   x = y = z = 50;

   /* Or */

3) int x = 50;
   int y = 50;
   int z = 50;

   /* Or */

4) int x, y, z = x = y = 50; /* This is madness. */

I find that declaring one variable per line (the 3rd approach) makes the code clearer and prevents asinine mistakes when declaring pointers.


> I also don't understand the actual meaning of the note "each
> undeclared identifier is reported only once for each function it
> appears in." Why is it appearing?

It means that the compiler will only report the first instance of an undeclared variable in a given function. For instance, if you have:

int x = y = z = 50;  /* Compiler only reports this instance */

z = 403;

The compiler will only report the first time z appears.


Footnote:

1
> Operators that are in the same cell (there may be several rows of
> operators listed in a cell) are evaluated with the same precedence, in
> the given direction. For example, the expression a=b=c is parsed as
> a=(b=c), and not as (a=b)=c because of right-to-left associativity.

答案2

得分: 1

你可以像这样将其分成多个部分:

int x=y

这是一个初始化,你在告诉计算机我需要一个名为x的整数,它等于y,但这个y是未声明的,因为你正在将它用作初始化的值,而不是声明它。

然后我们转向 y=z

现在你正在尝试将一个未声明的变量y与另一个未声明的变量z相互赋值。

然后 z=50;

这是一个赋值操作,而z从未被声明过,这是它在函数中的首次出现。

int 将被强制转换为左侧的第一个变量,以及每个逗号后的第一个变量(如果有)。之后的每个变量将被视为已声明的变量。

你的第二段代码有效,因为编译器已经知道你声明的每个变量,所以没有问题。

英文:

You can cut it into pieces like this :

int x=y

This is an initialization, you're telling the computer that i need an integer named x, that's equal to y, but this y is undeclared, because you're using it as a value to initialize with, not declaring it.

Then we go to y=z

Now you're trying to assign an undeclared variable y, with another undeclared variable z.

Then z=50;

This is an assignment, and z was never declared, this is its first appearance in the function.

int will be casted on the first variable to the left, and the first variable after every comma if available. Every variable after that will be considered as an already declared variable.

Your second piece of code works because the compiler already knows about each variable you declared, so there's no problem there.

huangapple
  • 本文由 发表于 2023年2月19日 15:23:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75498583.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定