如何在使用GCC“-Wextra”选项进行编译时初始化C结构而不产生警告?

时间:2013-05-01 12:39:29

标签: c gcc gcc-warning

#include <stdio.h>
#include <string.h>

typedef struct STest
{
  unsigned int uiRoll;
  unsigned short usiVal;
} TTest;

int main()
{
  TTest oTest = {0};  /* Initialize the Values with 0 */
  printf( "The values are: %d, %d\n", oTest.uiRoll, oTest.usiVal );
  return 0;
}

观察:

  1. 使用gcc -Wextra -o a aa.cpp
  2. 进行编译
  3. 获得警告:warning: missing initializer for member STest::usiVal
  4. 我也尝试过memset功能,但仍然收到相同的警告。
  5. 第一个结构元素没有警告信息。
  6. 如何初始化结构?所以没有警告信息。

4 个答案:

答案 0 :(得分:1)

为什么不初始化两个成员?

TTest oTest = {0, 0};

或者,可能更好:

TTest oTest = { .uiRoll = 0, .usiVal = 0};  

(这假设您确实正在编写C代码,该代码应使用gcc进行编译并使用.c的扩展名保存。如果将该代码保存在{{1}的文件中扩展名,.cpp将切换到C ++模式,并在第二个版本上失败。)

另一种选择:将编译器升级到GCC&gt; = 4.7.2(可能是普通的4.7.0就足够了)。该警告已被删除,您可以使用代码中的简短表单。

答案 1 :(得分:0)

甚至:

TTest oTest;
memset(&oTest, 0, sizeof(oTest));

我没有收到警告。你是如何尝试使用memset的?

答案 2 :(得分:0)

这个表示法是可移植/正确的一个零来初始化结构:

#include <stdio.h>
#include <string.h>

typedef struct STest
{
  unsigned int uiRoll;
  unsigned short usiVal;
}              TTest;

int main()
{
  /* Static declaration causes structure member's to be zeroed at instanciation */
  static const TTest zeroed_struct;

  /* Structure assignement is then safely used */
  TTest oTest = zeroed_struct;
  printf( "The values are: %d, %d\n", oTest.uiRoll, oTest.usiVal );
  return (0);
}

声明静态 TTest结构会导致编译器自动将所有结构字段设置为零。然后,您可以安全地使用赋值运算符将结构成员的另一个实例初始化为零。

在我看来,像你一样使用通用零初始化器是正确的。尽管如此,我在GCC bugtracker上发现了这篇有趣的帖子,它解释了为什么会对您的GCC版本发出警告,可能是4.4版本:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119

答案 3 :(得分:0)

除了在这种情况下GCC实际上可能是正确的事实之外,禁用警告的一般经验法则是将no-前缀添加到控制特定情况的警告消息的发出的选项。例如,如果您阅读gcc的手册页,它具有以下内容:

  

聚合具有初始值设定项,不会初始化所有成员。   此警告可以独立控制   -Wmissing场-初始化。

因此,要禁用此选项,您必须将-Wno-missing-field-initializers传递给GCC。

有趣的是,GCC 4.2.1发出此警告,而GCC 4.7.2则没有,即使明确启用了该警告。经过一些实验后,似乎如果指定一个0,则不会给出警告。但是,如果您指定两个或多个字段但不是全部,则会出现警告。

希望它有所帮助。祝你好运!