C89中的{0}初始化程序的标准如何? [英] How standard is the {0} initializer in C89?

查看:137
本文介绍了C89中的{0}初始化程序的标准如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我当前使用MISRA 2004标准的项目中,我们使用了三个GCC编译器,版本3.2.3、4.4.2和5.4.0.

In my current project, which uses the MISRA 2004 standard, we use three GCC compilers, versions 3.2.3, 4.4.2 and 5.4.0.

我们使用脚踏开关和c89标准以及大量其他限制运行构建检查.限制之一是必须在声明时初始化所有数据.

We run build checks with the pedantic switch and c89 standard and a load of other restrictions. One of the restrictions is that all data must be initialised at declaration.

我有一个问题,在GCC 3.2.3上,通用零初始化程序{0}仅针对基本单一类型的数组进行编译.如果我有一个结构数组,那么我会得到一个缺失的大括号警告,并且仅当我将{0}更改为{{0}}时,警告才会消失.

I have a problem in that on GCC 3.2.3, the universal zero initialiser {0} only compiles for arrays of the basic unitary types. If I have an array of structs, then I get a missing braces warning and the warning only goes away if I change {0} for {{0}}.

struct my_type my_thing[NUMBER_OF_THINGS] = {0};

成为

struct my_type my_thing[NUMBER_OF_THINGS] = {{0}};

但是,这对于具有struct成员的struct数组不起作用.然后问题出在4.4.2编译器上,该编译器会丢失缺少的初始化程序错误,因此我必须这样做:

This does not work, however, for arrays of structs which have struct members. Then the problem is with the 4.4.2 compiler, which gives missing initialiser errors, so I had to do this:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0}};

这满足了编译器的需求,但是它使我们的MISRA检查器跳了起来,因为MISRA需要通用的单个{0}初始化程序或完整的全数组初始化程序:

This satisfies the compilers, but it trips our MISRA checker, because MISRA demands either the universal single {0} initialiser or the full, whole-array initialiser:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0},
                                                                         {0, 0, {0}, 0},
                                                                         {0, 0, {0}, 0},
                                                                         {0, 0, {0}, 0},
                                                                         {0, 0, {0}, 0}};

这对我们来说是不切实际的,因为我们有各种各样的限制,并且NUMBER_OF_THINGS可能是可变的,并且在构建时会从源代码外部自动生成.

This is impractical for us because we have all sorts of restrictions and NUMBER_OF_THINGS may be changeable and be automatically generated from outside the source code at build time.

我想对老板说,所谓的通用初始化程序{0}足以初始化任何数组.我在GCC邮件列表和Bugzilla上发现了线程,这些线程可以追溯到很多年前,它们考虑了我提到的编译器警告是bug,并指出{0}是标准的一部分.但是,他们都没有提到哪个标准,而且我一直无法在ISO C89或C99草案或K& R v2中找到{0}. {0}是标准吗? 有什么方法可以保证将带有struct成员的struct数组初始化为全零(或NULL)?

I would like to be able to say to my boss that the so-called universal initialiser {0} is sufficient for initialising any array. I have found threads on the GCC mailing lists and Bugzilla, going back many years, which consider the compiler warnings I've mentioned to be bugs, and stating that {0} is part of the standard. However, none of them mention which standard, and I have been unable to find {0} in the ISO C89 or C99 drafts, or K&R v2. Is the {0} a standard? Is there any way to guarantee that an array of structs with struct members is initialised to all zeros (or NULL)?

问题在于,尽管我可以消除对MISRA代码的违反,但是我不确定这样做:

The trouble is that, while I can magic away the violations of the MISRA code, I am unsure that doing this:

struct my_struct_with_structs_inside my_other_thing[NUMBER_OF_THINGS] = {{0, 0, {0}, 0}};

...足以保证数组将完全归零.

...is sufficient to guarantee that the array will be completely zeroed.

任何人都可以从这个问题的根源中提供智慧吗?

Can anyone please offer wisdom from the root of this problem?

推荐答案

aggregate (意为数组或结构)中初始化所有对象的{0}初始化程序在任何版本的标准程序中都是100%标准的C.语法允许您省略子聚合的花括号.

The {0} initializer to initialize all objects in an aggregate (meaning array or struct) is 100% standard in any version of C. The syntax allows you to omit the braces for sub-aggregates.

我不会在这里讨论所有肮脏的细节.如果您对正式的规范文本感兴趣,可以在许多复杂的规则中进行解释,例如,您可以在§17及以后的C11 6.7.9中阅读这些规则.

I won't go into all the dirty details here. In case you are interested in the formal normative text, this is explained in a number of intricate rules that you can read about in for example C11 6.7.9 from §17 and forward.

关于MISRA-C:2004,此规则有点麻烦,因此有一个MISRA-C:2004 TC1.您的静态分析器可能未正确实现TC1 9.2,该声明指出顶层的{0}符合要求.

Regarding MISRA-C:2004, this rule was a bit cumbersome and there is a MISRA-C:2004 TC1 regarding it. Your static analyser might not properly implement TC1 9.2 which stated that {0} on the top level is compliant.

不过,TC1并没有完全解决所有问题.早在2008年,我就在这里问委员会:

Still, the TC1 didn't quite sort all things out. I asked the committee about this back in 2008 here:

https://www.misra.org. uk/forum/viewtopic.php?f = 65& t = 750

我收到的答复是委员会的正式答复,可以用作您文档中的参考.委员会同意该规则需要进一步改进,并在此基础上将该规则在MISRA-C:2012中进行了修复,其中{0}可以在任何地方用于初始化聚合类型的子对象.

The reply I got there is a formal committee response and may be used as reference in your documentation. The committee agreed that the rule needed further improvement and based on this the rule was fixed in MISRA-C:2012 where {0} may be used anywhere to initialize subobjects of aggregate type.

如果可能的话,我建议使用MISRA-C:2012.

I would recommend to use MISRA-C:2012 if possible.

这篇关于C89中的{0}初始化程序的标准如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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