首页 > 解决方案 > 如果缺少 const char* 数组初始化逗号,则生成编译器警告

问题描述

我在我的 C 代码中大量使用字符串文字表。这些表或多或少看起来像这样:

static const char* const stateNames[STATE_AMOUNT] =
{
    "Init state",
    "Run state",
    "Pause state",
    "Error state",
};

上面代码的问题是如果表格变长并且在开发过程中被修改,我有时会忘记逗号。代码编译时缺少逗号,但我的程序最终崩溃,因为最后一个字符串设置为NULL. 我使用了 MinGW 和 Keil 编译器来验证。

如果缺少逗号,有什么方法可以为我的初始化生成编译器警告?

标签: cinitialization

解决方案


将 every 包裹const char*在一对括号中应该可以解决问题,如下面的代码片段所示:

static const char* const stateNames[5] =
{
    ("Init state"),
    ("Run state"),
    ("Pause state")     //comma missing
    ("Pause state3"),
    ("Error state")
};

如果您忘记了逗号,您将收到类似于以下内容的编译错误:error: called object is not a function or function pointer

现场演示


请注意,如果您忘记了逗号,实际发生的情况是 C 将实际连接两个(或更多)字符串,直到下一个逗号或数组末尾。例如,假设您忘记了逗号,如下所示:

static const char* const stateNames[] =
{
    "Init state",
    "Run state",
    "Pause state" //comma missing
    "Pause state3" //comma missing
    "Error state"
};

int main(void)
{  
    printf("%s\n", stateNames[0]);
    return 0;    
}

这是gcc-9.2生成的(其他编译器生成类似的代码):

.LC0:
        .string "Init state"
        .string "Run state"
        .string "Pause statePause state3Error state" ; oooops look what happened
        .quad   .LC0
        .quad   .LC1
        .quad   .LC2
main:
        push    rbp
        mov     rbp, rsp
        mov     eax, OFFSET FLAT:.LC0
        mov     rdi, rax
        call    puts
        mov     eax, 0
        pop     rbp
        ret

很明显,最后三个字符串是连接在一起的,并且数组不是您期望的长度。


推荐阅读