我知道c中文件范围的初始值设定项的限制:你不能使用变量(甚至const),函数等......但我真的不明白为什么这不起作用:
#include <stdlib.h>
#include <stdio.h>
//unsigned long a = "string"[0] > '0'; // this does not compile
unsigned long a = 's' > '0'; // this works fine, output is "a = 1"
int main(void)
{
printf("a = %lu\n",a);
return 0;
}
为什么带有字符串文字的行给出:error:initializer元素不是常量。字符串文字不被视为常量吗?有没有办法让它发挥作用?
提前致谢
答案 0 :(得分:6)
您的变量具有静态存储持续时间,因此根据N1570(C11)§6.7.9/p4:
初始化程序中具有静态或。的对象的所有表达式 线程存储持续时间应为常量表达式或字符串 文字。
字符串文字具有静态存储持续时间 §6.4.5/p6 ,因此它们的地址可以被视为常量表达式(这就是允许它们作为初始化程序的原因)。但是你试图在这样的地址访问该值,并且C标准明确禁止它。引用§6.6/p9,强调我的:
地址常量是空指针,是指向左值的指针 指定静态存储持续时间的对象,或指向a的指针 功能指示符;它应该使用一元&amp; amp; 运算符或整数常量强制转换为指针类型,或隐式地通过 使用数组或函数类型的表达式。的的 array-subscript []和成员访问。和 - &gt;运营商,地址&amp; 和间接*一元运算符,以及指针强制转换可以用于 创建一个地址常量,但对象的值应该是 不能通过使用这些运营商来访问。
另一方面,当您使用字符常量进行比较时,您将获得有效的常量表达式。
答案 1 :(得分:2)
在C语言中,具有静态存储持续时间的对象必须使用常量表达式或使用包含常量表达式的聚合初始值设定项进行初始化。
现在你基本上MP4Box -dash-live 8000 -subdur 8000 -profile dashavc264:live -mpd-refresh 240.0 -time-shift 24 -min-buffer 4000 -insert-utc -no-cache -out manifest.mpd format-1080.mp4#video format-360.mp4#video format-1080.mp4#audio format-360.mp4#audio
作为一个常量表达式?但是这样吗?
事情是从6.6p2
可以在转换期间而不是运行时期间计算常量表达式,因此可以在常量可以使用的任何位置使用。
之后我检查了translation phases以及它包含的内容:
很明显,没有一个表达式被评估涉及"string"[0]
数组下标字符串文字。这实际上涉及解除引用地址并获得在翻译阶段无法做到的vlaue。这就是为什么这个错误。