2

全部,

我有以下 C 代码,当我编译时,

static struct 
{
    const char* val;
    const char* parse_key;
    int len;  //parse key length
    void (*parse_routine) (const char* after, rtsp_sdp_t* response);
} sdp_header[] =
{
#define SDP_FILL_STRUCT(a,b) {#a, b, strlen(b), sdp_##a}
    SDP_FILL_STRUCT(attr_control, "a=control:"),    
    SDP_FILL_STRUCT(attr_framerate,"a=framerate:"),
    SDP_FILL_STRUCT(attr_range, "a=range:"),    
    {'\0', '\0', 0, (void*)0},  

};

为什么它会给出以下错误:

:330: warning: initializer element is not constant
:330: warning: (near initialization for 'sdp_header[0]')
:331: warning: initializer element is not constant
:331: warning: (near initialization for 'sdp_header[1]')
:332: warning: initializer element is not constant
:332: warning: (near initialization for 'sdp_header[2]')
:333: warning: initializer element is not constant

不知道具体是什么原因,求大神帮忙看看。谢谢

4

2 回答 2

5

在 C89/90 中,所有用大括号括起来的初始值设定项都必须是常量。在 C99 和更高版本中,用于具有静态存储持续时间的对象的大括号括起来的初始化程序必须是常量。

这就是您的情况:sdp_header是一个具有静态存储持续时间的数组,这意味着您只能在{}.

似乎您的所有初始化程序都是常量之外的常量strlen。函数调用不会产生常量。在您的特定情况下,您可以替换strlensizeof

#define SDP_FILL_STRUCT(a,b) {#a, b, sizeof b - 1, sdp_##a}

但它仅在b代表文字字符串时才有效(在您的示例中就是这种情况)。

此外,您的最后一个初始化程序要么错误,要么具有误导性,具体取决于您的意图。最后一个元素的值valparse_key应该是什么?如果你想要空字符串,那么它应该是

{ "", "", 0, NULL }

如果你想要空指针,那么它应该是

{ NULL, NULL, 0, NULL }

或者

{ 0, 0, 0, 0 }

甚至仅仅是

{ 0 }

您的 current'\0'将用作空指针常量,但指定空指针常量是一种误导和奇怪的方式。

以及为什么0void *为函数指针成员设置外壳也不清楚。为什么?只写NULL或平原0。无需演员。如果你想要一个演员,至少把它转换成正确的类型。是从哪里来void *的?

于 2013-11-04T06:09:27.340 回答
3

这是因为2个问题:

const char* val;
const char* parse_key;

#define SDP_FILL_STRUCT(a,b) {#a, b, strlen(b), sdp_##a} //strlen(b)

问题1:

strlen在编译时不被评估..所以编译器抱怨..strlen只会在运行代码时被评估。

请注意,某些编译器可能能够将其优化为编译时常量,但这并不能假设您被允许做您正在尝试做的事情。

问题2:(来源:https ://stackoverflow.com/a/3025106/1253932 )

在 C 语言中,术语“常量”是指文字常量(如 1、'a'、0xFF 等)和枚举成员。常量限定的对象(任何类型)在 C 语言术语中不是常量。无论它们的类型如何,它们都不能用于具有静态存储持续时间的对象的初始化程序。

例如,这不是一个常数

const int C = 5; /* `C` is not a constant in C */

上面的 C 将是 C++ 中的常量,但它不是 C 中的常量。所以,如果你尝试这样做

static int j = C; /* ERROR */

你会得到同样的错误:试图用非常量初始化一个静态对象。

于 2013-11-04T05:19:28.860 回答