gpt4 book ai didi

C99 指定初始化程序重复索引在构建输出或 lint 中根本没有标记

转载 作者:行者123 更新时间:2023-12-03 23:31:30 26 4
gpt4 key购买 nike

前几天我玩了一下指定的初始化程序,令我惊讶的是,多次使用同一个索引是有效的。更重要的是,当我这样做时,它甚至没有产生编译器警告、错误甚至信息性声明,甚至 PC-Lint 似乎也不在乎(我认为这最让我感到惊讶)。

我想知道在这种情况下编译器是否有原因甚至不提供信息消息,或者是否有额外的编译器/lint/等。可用于捕获或标记此问题的选项。

使用的工具:Renesas RX Standard Toolchain v1.2.0.0 (C99)、gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1)(在 VM 中)、Lint-NT 9.00i

例如,我正在处理的一些旧代码 #defines 一堆命令,然后创建一个命令结构数组(此处大大简化)以循环查找和使用该特定命令:

#define CMD_RMEM 0
#define CMD_WMEM 1
#define CMD_XCRC 2
#define CMD_NULL 3

typedef struct
{
const char cmdID;
const char* cmdStr;
} CMD;

const CMD commands[] = {
{CMD_RMEM,"RMEM"},
{CMD_WMEM,"WMEM"},
{CMD_XCRC,"XCRC"},
{CMD_NULL,"NULL"},
};

然后我想起了我在某处看到的指定初始化语法,并认为除了检测重复的命令索引之外,它还可以为数组中项目的排列提供更大的灵 active ,例如:
//(same #def's & typedef as above)
const CMD commands[] = {
[CMD_RMEM] = {CMD_RMEM,"RMEM"},
[CMD_NULL] = {CMD_NULL,"NULL"}, //different order in ititializer list,
// but designation keeps it in the same array/memory position, so
// this will still be the 'last' element
[CMD_CMEM] = {CMD_CMEM,"CMEM"},
[CMD_WMEM] = {CMD_WMEM,"WMEM"},
[CMD_XCRC] = {CMD_XCRC,"XCRC"},
};

会产生与上面的初始代码相同的效果,但可以灵活地安排数组声明中的项目(它确实如此)和(我在想/希望)
#define CMD_RMEM 0
#define CMD_WMEM 1
#define CMD_XCRC 1 // obvious dupe in a short list, but not so obvious
// if part of a much longer list or if split among multiple files
#define CMD_NULL 2

// (Same designated initializer section as above)

至少会产生一个警告,因为我们不止一次使用相同的指定索引(它 )(这个例子很容易通过添加命令而不移动最后一个 NULL 占位符)。

GCC Designated Inits页面注释了一个 GNU 扩展,它允许您在初始化程序中使用范围,我可以看到它对定义整个范围然后覆盖某些部分的能力很有用(例如 int arr[] = {[0 ... 99] = -1, [42] = 1} ,但我不明白为什么它仍然不是至少在某种程度上被标记...

在同一个 GCC 页面的更下方,它确实解决了多个字段的主题,但没有解释它为什么会这样:“如果同一个字段被多次初始化,它具有上次初始化的值。如果有的话这种重写的初始化有副作用,不确定是否发生副作用。目前,GCC 会丢弃它们并发出警告。

This IBM page也展示了一个有趣的例子,但仍然没有回答(至少对我来说)为什么它至少不是某种构建消息......

最后,这个 gcc patch page从 2000 年 12 月开始,表明重复检查已被明确删除,但没有(根据我简要阅读的内容)解释原因。

那么,为什么这(似乎)被掩盖了?有没有办法让编译器(甚至 lint)标记这个(以提供更多安全性)(在 c/c99 中;不要只说“使用 c++”或其他东西:p)?

最佳答案

我没有解释为什么——也许仅仅是因为指定的初始化器仍然是新的并且很少使用。编译器制造商必须考虑将从新功能中受益的程序员数量。

Clang 警告您的构造:

$ clang  -std=c99 -Wall -c t.c
t.c:24:17: warning: initializer overrides prior initialization of this subobject [-Winitializer-overrides]
[CMD_XCRC] = {CMD_XCRC,"XCRC"},
^~~~~~~~
t.c:4:18: note: expanded from macro 'CMD_XCRC'
#define CMD_XCRC 1 // obvious dupe in a short list, but not so obvious
^
t.c:23:17: note: previous initialization is here
[CMD_WMEM] = {CMD_WMEM,"WMEM"},
^~~~~~~~
t.c:2:18: note: expanded from macro 'CMD_WMEM'
#define CMD_WMEM 1
^

(我必须对其进行一些小改动才能编译,但你明白了。)
$ clang -v
Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.3.0
Thread model: posix

关于C99 指定初始化程序重复索引在构建输出或 lint 中根本没有标记,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16742467/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com