我在C代码中经常使用字符串文字表.这些表格或多或少都是这样的:

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

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

如果逗号丢失,有没有办法为我的初始化生成编译器警告?

推荐答案

将每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的编译错误

LIVE DEMO


请注意,如果您忘记了逗号,实际发生的情况是,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 generates(其他编译器生成类似代码):

.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

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

C++相关问答推荐

函数指针始终为零,但在解除引用和调用时有效

是否定义了数组指针类型转换为指针类型?""""

字符串令牌化xpath表达式

来自stdarg.h的c中的va_args无法正常工作<>

创建一个fork导致fget无限地重新读取文件

为什么net/if.h在ifaddrs.h之前?

如何在下面的C代码中正确管理内存?

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

我的C函数起作用了,但我不确定为什么

将某些内容添加到链接列表时,列表中的其他项将使用最后添加的项的名称

如何在MSVC中使用intSafe.h函数?

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

浮点正零何时不全为零?

变量值不正确的问题

memcmp 是否保证按顺序比较字节?

GDB 跳过动态加载器代码

C11 嵌套泛型

无法在 C 中打开文本文件,我想从中读取文本作为数据并将其写入数组

C99 的 %zu 格式说明符不起作用

定义 int a = 0, b = a++, c = a++;在 C 中定义了行为吗?