前几天我玩了一下指定的初始化器,令我惊讶的是,多次使用相同的索引是有效的。更重要的是,当我这样做时,它甚至没有产生编译器警告、错误,甚至信息语句,甚至 PC-Lint 似乎也不关心(我认为这最让我惊讶)。
我想知道在这种情况下编译器是否有原因甚至不提供信息消息,或者是否有其他编译器/lint/等。可用于捕获或标记此问题的选项。
使用的工具:Renesas RX 标准工具链 v1.2.0.0 (C99)、gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1)(在虚拟机中)、Lint-NT 9.00i
例如,我正在处理的一些旧代码#定义了一堆命令,然后创建一个命令结构数组(此处大大简化)以循环查找和使用该特定命令:
#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"},
};
然后我想起了我在某处看到的指定初始化语法,并认为除了检测重复的命令索引之外,它还可以在数组中的项目排列上提供更大的灵活性,例如:
//(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)
会产生at least警告,因为我们多次使用相同的指定索引(它does not)(此示例可以很容易地通过添加命令而不移动最后一个 NULL 占位符来实现)。
The GCC 指定初始化 http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html页面指出了一个 GNU 扩展,它允许您在初始化程序中使用范围,我认为它非常有用,能够定义整个范围,然后覆盖某些部分(例如int arr[] = {[0 ... 99] = -1, [42] = 1}
,但我不明白为什么它仍然没有至少标记为some等级...
在同一 GCC 页面的更下方,它确实解决了多个字段的主题,但没有解释其行为的原因:“如果多次初始化同一字段,则它具有上次初始化的值。如果有的话这种重写的初始化有副作用,是否会发生副作用尚不清楚。目前,GCC 丢弃它们并发出警告。
此 IBM 页面 http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/designators.htm也展示了一个有趣的例子,但仍然没有回答(至少对我来说)为什么它不是at least某种构建消息...
最后,这个海湾合作委员会补丁页 http://gcc.gnu.org/ml/gcc-patches/2000-12/msg00402.html从 2000 年 12 月开始,明确表明重复检查removed,但没有(根据我简要阅读的内容)解释原因。
那么,为什么这(看似)被掩盖了呢?有没有什么方法可以让编译器(甚至 lint)标记这个(以提供更多安全性)(在 c/c99 中;不要只说“使用 c++”或其他东西:p)?