GCC 对 int *a = 1,2,3,4,5 的语句做了啥?

Posted

技术标签:

【中文标题】GCC 对 int *a = 1,2,3,4,5 的语句做了啥?【英文标题】: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 指向一个整数。 【参考方案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中存储的值无关。

【讨论】:

以上是关于GCC 对 int *a = 1,2,3,4,5 的语句做了啥?的主要内容,如果未能解决你的问题,请参考以下文章

主要几个发行版的 gcc 对 c++ 新标准的支持情况区别

Cent OS 6.5下安装gcc-5.3.0

CentOS6.5 gcc升级到4.8.2

java二维数组int[][]a=1,2,3,,4,5,6,7,8,9啥意思,

包含int a:2的这个结构体占几个字节呢?

有以下程序: main( ) int a[10]=1,2,3,4,5,6,7,8,9,10,*p=&a[3],*q=p-2; printf("%d\n",*p+*q);