为什么不能使用复合文字分配已定义的固定大小的数组?

dav*_*rle 3 c arrays compound-literals designated-initializer

为什么在使用复合文字(示例代码中的情况 b)定义结构后可以分配结构,而数组不能(情况 c))?

我知道情况 a) 不起作用,因为当时编译器不知道分配的 rhs 上的内存布局。它可以是任何类型的演员表。但是按照这条线,在我看来,c) 是一个完美定义的情况。

typedef struct MyStruct {
  int a, b, c;
} MyStruct_t;

void function(void) {
  MyStruct_t st;
  int arr[3];

  // a) Invalid
  st = {.a=1, .b=2, .c=3};
  // b) Valid since C90
  st = (MyStruct_t){.a=1, .b=2, .c=3};
  // c) Invalid
  arr = (int[3]){[0]=1, [1]=2, [2]=3};
}
Run Code Online (Sandbox Code Playgroud)

编辑:我知道我不能分配给一个数组 - 这是 C 的设计方式。我可以使用 memcpy 或单独分配值。

阅读下面的评论和答案后,我想现在我的问题分解为一个永远争论不休的难题,即为什么不能分配给数组。

更令人费解的是,正如这篇文章和下面MM的评论所建议的那样,以下分配是完全有效的(当然,它违反了严格的别名规则)。您可以将数组包装在结构中并进行一些讨厌的转换来模拟可分配的数组。

typedef struct Arr3 {
  int a[3];
} Arr3_t;

void function(void) {
  Arr3_t a; 
  int arr[3];

  a = (Arr3_t){{1, 2, 3}};
  *(Arr3_t*)arr = a;
  *(Arr3_t*)arr = (Arr3_t){{4, 5, 6}};
}
Run Code Online (Sandbox Code Playgroud)

那么是什么阻止开发人员将这样的功能包含在C22(?)

R..*_*R.. 5

C没有数组的分配,在所有。也就是说,wherearray有任何数组类型,array = /* something here */无论“something here”的内容如何,都是无效的。它是否是复合文字(您似乎将其与指定初始值设定项混淆,这是一个完全不同的概念)无关紧要。array1 = array2将同样无效。

至于为什么它无效,在某种程度上,这是 C 语言及其设计的动机/基本原理的问题,无法回答。然而,机械地,任何上下文中的数组,除了指向它们的第一个元素的指针的操作数sizeof&“衰减”的操作数。所以在以下情况下:

arr = (int[3]){[0]=1, [1]=2, [2]=3};
Run Code Online (Sandbox Code Playgroud)

您试图将指向复合文字数组第一个元素的指针分配给非左值(arr衰减时产生的右值)。当然,这是无稽之谈。

  • 它不会自动假设该类型是赋值目标的类型。它不是初始化,而是赋值。这是一个很大的区别。 (4认同)