为什么在定义初始化到未命名数组的函数作用域的static指针时,GCC和Clang分别显示"错误:初始化程序元素不是常量"和"错误:初始化程序元素不是编译时常量";但是,当在文件范围内定义指向相同的未命名数组的相同静态指针时,他们处理得很好.

我已经使用针对嵌入式硬件的编译器编译了相同的程序,编译没有错误.

以下是错误处于活动状态的代码片段:

int foo()
{
    static int *ptr = (int[]) { 9, 8, 7 }; /* COMPILE ERROR */
    return ptr[2];
}

int main(void)
{
    return foo();
}

这里有一个类似的代码片段,在文件范围内带有static指针,GCC和Clang编译时没有出现问题:

static int *ptr = (int[]) { 9, 8, 7 }; /* File-scope is fine */

int foo()
{
    return ptr[2];
}

int main(void)
{
    return foo();
}

当然,我可以在我的函数中定义一个单独的静态数组,并将我的静态指针指向该数组,但我想使用一个未命名的array.我try 了不同的编译器标志,但都无济于事:

  • -std=c90
  • -std=c99
  • -std=c11
  • -std=gnu11

推荐答案

问题出在复合文字的作用域(即您的"未命名数组");当它在file scope处使用时(如您的第二个代码片段所示),那么C标准指定它有static个存储持续时间,因此它可以用作初始值设定项.

然而,声明为block scope的复合文字(如您的第一个示例)有automatic个存储持续时间,因此它的地址不能在此上下文中用作初始值设定项.

this Draft C11 Standard人起:

6.5.2.5 Compound literals


5     The value of the compound literal is that of an unnamed object initialized by the initializer list. If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

C++相关问答推荐

为什么海湾合作委员会在共享对象中的. init_data的虚拟内存地址之前留出一个空白

在C语言中使用scanf()时我无法理解的警告

由Go调用E.C.引起的内存快速增长

手动矢量化性能差异较大

为什么输出不是从上到下C

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

当execvp在C函数中失败时杀死子进程

将 struct 变量赋给自身(通过指针取消引用)是否定义了行为?

C在声明带有值的数组时,声明大小有用吗?

对重叠字符串使用MemMove

关于scanf()和空格的问题

C语言中奇怪的输出打印数组

如何摆脱-WIMPLICIT-Function-声明

有没有办法减少C语言中线程的堆大小?

函数的typedef是标准 C 语法吗?它与函数指针的typedef有何不同?

为什么 int32_t 和 int16_t 在 printf 输出中具有相同的位数?

子进程不会修改父进程中的统计信息

int 与 size_t 与 long

char* 上的 free() 被 valgrind 识别为无效

这种 C 函数风格的名称是什么?