gcc编译错误:强制转换指定数组类型

gcc编译错误:强制转换指定数组类型,c,gcc,C,Gcc,以下代码完全有效 int *ia = (int[]){1,3,5,7}; 但当我编译下一行代码时 char *p = (char[]) "abc"; 海湾合作委员会说 test.c:87: error: cast specifies array type 看起来他们是以同样的方式铸造的。为什么第二个会收到错误消息 正如你们所说,“abc”是一个指针,不能转换成指针。所以我的另一个问题是:为什么 char[] s = "abc"; 这是有效的。编译时,上面这行代码是如何工作的?“abc

以下代码完全有效

int *ia = (int[]){1,3,5,7};
但当我编译下一行代码时

char *p = (char[]) "abc";
海湾合作委员会说

test.c:87: error: cast specifies array type
看起来他们是以同样的方式铸造的。为什么第二个会收到错误消息


正如你们所说,“abc”是一个指针,不能转换成指针。所以我的另一个问题是:为什么

 char[] s = "abc";

这是有效的。编译时,上面这行代码是如何工作的?

“abc”
不能强制转换为字符数组,因为它不是以数组开头的。 char[]和char*之间存在巨大的差异:第一个是数组本身,第二个是指向数组的指针。以下各项应有效(并非100%确定):


这是有效的,因为右侧的表达式是C99复合文字,而不是强制转换:

int *ia = (int[]){1,3,5,7};    /* Valid */
但是,这是无效的,因为它是强制转换表达式,而不是复合文字。正如GCC告诉您的,您不能强制转换为数组类型:

char *p = (char[]) "abc";     /* NOT Valid */
您可以通过使其成为适当的复合文字来修复它-它们由大括号表示:

char *p = (char[]){"abc"};    /* Valid */
:

  • 由括号中的类型名和括号中的初始值设定项列表组成的后缀表达式是复合文字。它提供一个未命名的对象,其值由初始值设定项列表给定
  • (我的重点)

    也就是说,在括号中键入
    (char[])
    ,然后键入括号内的初始值设定项列表
    {a',b',c','\0'}

    自第6段以来。说

  • 6.7.9中初始值设定项列表的所有语义规则也适用于复合文字
  • 6.7.9p14表示

  • 字符类型的数组可以由字符串文字或UTF-8字符串文字初始化,也可以用大括号括起来。字符串文本的连续字节(如果有空间或数组大小未知,则包括终止的空字符)初始化数组的元素
    您也可以使用
    (char[]){“abc”}
    达到相同的效果。请注意,尽管
    6.7.9p14
    允许从不带大括号的字符串初始化
    char
    数组,但复合文本的规则否认了这一点,因为
    (char[])“abc”
    看起来像一个演员。

    “abc”绝对是一个数组-请参见
    abc
    的大小。问题是你永远不能对数组进行强制转换-第一个不是强制转换(尽管它看起来像一个)。@caf:sizeof“abc”表示4,这对于在许多系统上它是数组还是指针来说都不是决定性的。但你当然是对的,因为尝试各种尺寸的衣服很快就会证明;-)这很好,因为现在我可以这样做了:sizeof((char[]){“abcde”}@Michael:你可以一直做
    sizeof“abcde”
    ,这是完全相同的-复合文字和字符串文字之间的唯一区别是复合文字是可修改的,并且字符串文字可以与其他字符串文字共享存储。
    char *p = (char[]) "abc";     /* NOT Valid */
    
    char *p = (char[]){"abc"};    /* Valid */