C99指定的初始化复制指数不是在所有在建输出或棉绒标记 [英] C99 Designated Initializer duplicate index not flagged at all in build output or lint

查看:222
本文介绍了C99指定的初始化复制指数不是在所有在建输出或棉绒标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我指定的初始化发挥了一下周围有一天,发现,出乎我的意料,它是有效使用相同的指数超过一次。更重要的是,它甚至没有产生一个编译器警告,错误,或者当我这样做,甚至PC-林特似乎并不关心(我认为最让我吃惊)。

I played around with designated initializers a bit the other day and noticed, to my surprise, that it is valid to use the same index more than once. What's more, it didn't even produce a compiler warning, error, or even informational statement when I did so, and even PC-Lint didn't seem to care (which I think surprised me the most).

我不知道是否有一个为编译器甚至没有提供在这种情况下,如果一个信息消息的原因有额外的编译/皮棉/等。这可能是可用选项赶上或标志这一点。

I'm wondering if there's a reason for compilers not even providing an information message in this case or if there are additional compiler/lint/etc. options that may be available to catch or flag this.

所使用的工具:瑞萨RX标准工具链v1.2.0.0(C99),GCC 4.4.3版(Ubuntu的4.4.3-4ubuntu5.1)(在虚拟机),皮棉-NT 9.00i

Tools used: Renesas RX Standard Toolchain v1.2.0.0 (C99), gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5.1) (in a VM), Lint-NT 9.00i

例如,一些老的code,我在工作的#defines一堆命令,然后创建指挥结构(这里彻底简化)的阵列要通过循环找到并使用特定的命令:

For example, some old code I'm working on #defines a bunch of commands and then creates an array of command structures (drastically simplified here) to be cycled through to find and use that particular command:

#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"},
};

然后我记得我已经看到某处指定的初始化语法,并认为这可能会检测到重复命令指数,例如提供除数组中的项的安排更灵活:

Then I remembered the designated initializer syntax I'd seen somewhere and thought it may provide more flexibility on the arrangement of items in the array in addition to detecting duplicate command indices, e.g.:

//(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"},
};

会产生作为初始code以上但具有灵活性同样的效果在数组声明布置的物品(其它)和(我想/希望),该

would produce the same effect as the initial code above but with flexibility in arranging the items in the array declaration (which it does) and (I was thinking/hoping) that

#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占位符)。

would generate at least a warning since we're using the same designated index more than once (which it does not) (this example may easily result from adding a command without shifting the last NULL placeholder).

借助 GCC指定Inits 页笔记GNU扩展,它允许你使用在初始化,这点我可以看到是非常有用与定义的整个范围,然后覆盖某些部件的能力范围(例如: INT ARR [] = {[0 ... 99] = -1 ,[42] = 1} ,但我不明白为什么它仍然不是至少在标记的部分的水平...

The GCC Designated Inits page notes a GNU extension which allows you to use ranges in the initializers, which I can see being useful with the ability to define the whole range and then override certain parts (e.g. int arr[] = {[0 ... 99] = -1, [42] = 1}, but I don't understand why it's still not at least flagged at some level...

在同一页面GCC更远了下来,它确实满足多个领域的话题,但没有解释为什么它表现为它的作用:如果同一个字段被初始化多次,它已经从过去的初始值如果任何这样的覆盖初始化有副作用,这是不确定的副作用是否发生。目前,GCC丢弃它们,并发出警告。

Farther down in the same GCC page, it does address the topic of multiple fields, but doesn't explain why it behaves as it does: "If the same field is initialized multiple times, it has the value from the last initialization. If any such overridden initialization has side-effect, it is unspecified whether the side-effect happens or not. Currently, GCC discards them and issues a warning."

<一个href=\"http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/designators.htm\"相对=nofollow>这个IBM 页面显示了一个有趣的例子为好,但仍然没有回答(至少对我来说),为什么它不是的至少的某种版本的消息...

This IBM page shows an interesting example as well, but still doesn't answer (at least for me) why it is not at least some sort of build message...

最后,来自该 GCC补丁页 2000年12月表示重复检查已明确的删除的,但不会(从我读简述)解释原因。

And finally, this gcc patch page from Dec 2000 indicates duplicate checks were explicitly removed, but doesn't (from what I read briefly) explain why.

那么,这是为什么(貌似)轻轻带过?而且是有什么办法可以让编译器(甚至皮棉)标志这一(提供更安全)(在C / C99;不要只说用C ++或东西:P)?

So, why is this (seemingly) glossed over? And is there any way to have the compiler (or even lint) flag this (to provide more safety)(in c/c99; don't just say 'use c++' or something :p)?

推荐答案

我也没有解释为什么-perhaps只是因为指定的初始化程序还是新的,很少使用。编译器厂商必须要考虑谁的程序员将从新功能中受益的人数。

I have no explanation as to why —perhaps simply because designated initializers are still new and little-used. Compiler makers have to consider the number of programmers who will benefit from new features.

锵提醒您的结构:

$ 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
                 ^

(我不得不做出细微的变化为它编译,但你的想法。)

(I had to make minor changes for it to compile but you get the idea.)

$ 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指定的初始化复制指数不是在所有在建输出或棉绒标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆