【问题标题】:What did GCC do to the statement of int *a = {1,2,3,4,5}?GCC 对 int *a = {1,2,3,4,5} 的语句做了什么?
【发布时间】:2018-09-01 15:09:59
【问题描述】:
#include <stdio.h>
int main(){
  int *a = {1,2,3,4,5};
  printf("a:%x &a:%x\n",a,&a);
  return 0;
}

我用 GCC 编译了这个程序。 a 的输出是1&amp;a 的输出是一个地址。 GCC 对int *a = {1,2,3,4,5} 做了什么? GCC 是否将其视为一个数组或指向数组或其他东西的指针?

【问题讨论】:

  • 不要贴代码图片,贴实际代码。
  • 不是因为我们无法读取代码的图像,而是因为它们是代码,应该这样发布。有人可能还想复制并粘贴它来运行它。
  • Array automatically decay into pointer 在大多数情况下。
  • int *a = {1,2,3,4,5}; 真的吗?
  • 逗号在此处用作运算符。这就是为什么你得到 a=1 因为 a={1,2,3,4,5} 等同于 "(a = 1),2,3,4,5" 。并且 *a 指向一个整数。

标签: c gcc


【解决方案1】:

我没有参考 C 标准,但您可以从编译警告消息中看到 gcc 如何处理此问题:

[STEP 101] # cat foo.c
int main()
{
    int * a = {1, 2};
    return !!a;
}
[STEP 102] # gcc -Wall foo.c
foo.c: In function ‘main’:
foo.c:3:16: warning: initialization makes pointer from integer
without a cast [-Wint-conversion]
     int * a = {1, 2};
                ^
foo.c:3:16: note: (near initialization for ‘a’)
foo.c:3:19: warning: excess elements in scalar initializer
     int * a = {1, 2};
                   ^
foo.c:3:19: note: (near initialization for ‘a’)
[STEP 103] #

更新:

刚刚查看了C99 standard,并在6.7.8 初始化部分找到了这个:

标量的初始值设定项应该是一个表达式,可选地用大括号括起来。

【讨论】:

    【解决方案2】:

    该代码违反了约束,因为非聚合的初始值设定项只能包含 1 个元素。

    GCC 有一个“扩展”来忽略多余的初始化程序,因此它将代码视为int *p = 1;。这也是违反约束的,因为不能将整数分配给指针。但是 gcc 有另一个“扩展”来处理 int *p = (int *)1; 这样的代码。所以你最终会得到一个指向地址 1 的指针。

    &a 的输出是一个地址。

    &amp;a是变量a在内存中的地址,这与a中存储的值无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 2011-08-27
      • 2014-12-22
      • 1970-01-01
      • 2021-09-17
      • 2017-07-17
      相关资源
      最近更新 更多