2013-05-01 66 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

相關問題