c - 数组初始化中数组元素的赋值

标签 c initialization language-lawyer

<分区>

考虑以下简单程序:

#include <stdio.h>

int main(void)
{
    int a[5] = { a[2] = 1 };
    printf("%d %d %d %d %d\n", a[0], a[1],a[2], a[3], a[4]);
}

在 GCC 7.3.0 中输出

1 0 1 0 0

Considering that a[1] is zero, it seems that the initialization is similar to

int a[5] = { 1 };
a[2] = 1;

问题是:虽然初始化器可以是任何泛型表达式,但初始化和赋值的顺序是什么?

这是否有效且定义明确?它可以是实现定义的、未定义的还是未指定的?


这个问题与问题Confusion about Array initialization in C相关.

最佳答案

虽然我不能说我是 ISO 专家,但这是我在 godbolt 的帮助下发现的.

首先,我在 -fsanitize=undefined 的帮助下构建了示例,这很好地表明了未定义的行为。 GCC 和 clang 都没有提示。

接下来我查看了 gcc 执行的各个阶段,在本例中为 gimple阶段

foo ()
{
  int a[5];

  try
    {
      # DEBUG BEGIN_STMT
      a = {};
      a[2] = 1;
      _1 = a[2];
      a[0] = _1;
      # DEBUG BEGIN_STMT
      _2 = a[4];
      _3 = a[3];
      _4 = a[2];
      _5 = a[1];
      _6 = a[0];
      printf ("%d %d %d %d %d\n", _6, _5, _4, _3, _2);
    }
  finally
    {
      a = {CLOBBER};
    }
}

在这里你可以看到,首先定义了数组a,然后将1赋值给a[2],然后就是结果(1,因为 it is an assignment )被分配给 a 的第一个元素。索引中的另一个保留为 0,因此打印出模式 1 0 1 0 0

关于c - 数组初始化中数组元素的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52307772/

相关文章:

c 扫描文件夹中的新文件

c - 可执行文件的内存布局

c - 初始化一个结构对象数组,这些对象之前存储在结构变量中

c++ - 这组运算符会导致未定义的行为吗?

sql - 外部查询的 FROM 子句中不存在派生表?

头文件中的 C typedef 在文件范围内可变修改

c - 如何在c中创建霍夫曼树(已经有一个排序数组)

C# 等效于具有 init block 的 Java 匿名内部类

c++ - 为什么我可以使用列表初始化普通数组而不使用赋值运算符

c++ - GCC不喜欢使用匿名命名空间转发声明来结交 friend ,但是MSVC愿意。什么?