2013-05-01 194 views
3
#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; 
} 

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

  1. 编译与gcc -Wextra -o a aa.cpp
  2. 在收到警告:warning: missing initializer for member STest::usiVal
  3. 我也与memset的功能,但仍然得到同样的警告尝试。
  4. 第一个结构元素没有警告消息。

如何初始化结构?所以没有警告信息。

+0

用'-Wno-missing-field-initializers'? – 2013-05-01 12:42:34

+3

使用'gcc x.c'或者'g ++ x.cpp'会阻止很多未来的消息 – technosaurus 2013-05-01 12:49:36

+0

@ShafikYaghmour建议很好。使用适当的编译器调用,使用g ++编译C++源代码,使用gcc编译C源代码。您当然可以通过调用gcc来编译C++源代码,但是您需要手动传递很多选项才能获得更好的行为。 – 2013-05-01 12:59:55

回答

1

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

TTest oTest = {0, 0}; 

,或者可能更好:

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

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

另一种选择:将编译器升级到GCC> = 4.7.2(可能普通的4.7.0将是en ough)。该警告被删除,您可以使用代码中的简短格式。

+0

这并不总是可能的,就好像你有一个具有大量元素和大量嵌套结构的结构。那么初始化所有成员变量将会是一个大问题。 – Subhajit 2013-05-01 13:11:10

+0

@Subhajit然后将C编译为C. C只有一个显式初始化程序没有问题,6.7.9(19)指定所有其他字段/元素都被初始化为一个合适的零值。 – 2013-05-01 13:13:10

+0

@Daniel:至少在版本4.5和4.6.3中,GCC仍然警告说。 4.7和4.8都可以。 – Mat 2013-05-01 13:16:01

0

甚至:

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

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

+0

这种表示法具有不可移植性的缺点,使用通用零初始化器是最好的选择。 – 2013-05-01 12:48:36

+0

是的,你是对的:) – Subhajit 2013-05-01 13:01:20

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

0

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

聚合具有不初始化所有成员的初始化程序。 此警告可以独立控制 -Wmissing-field-initializers。

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

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

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

+1

这似乎是GCC团队报告和验证的错误:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119。这可以解释为什么这个警告不再在'4.7.2'中发布。 – 2013-05-01 13:02:38

相关问题