[英]Why GCC compiles this erroneous code?
我試圖編譯類似:
struct A
{ int a;
struct B
{ int c;
};
};
現在,當我編譯這段代碼時,編譯器會向我顯示一條警告消息:
declaration does not declare anything [enabled by default]
我知道我還沒有定義struct B
任何實例。 那將意味着我將無法訪問變量c
。 仍然編譯器會編譯此代碼並顯示警告。 重點是什么? 為什么編譯器不給出編譯錯誤呢?
添加的信息:
struct A
的大小等於我機器上int
的大小!
因為您可以這樣做:
struct A
{ int a;
struct B
{ int c;
};
};
int main()
{
struct A a = {1};
struct B b = {2};
return a.a + b.c;
}
注意:
B
,您需要使用分號(缺少代碼) A::B
,但是C的作用域規則不同(實際上所有結構都屬於全局結構名稱空間) 至於允許它的動機...
struct Outer {
struct {
int b;
} anon;
/* this ^ anonymous struct can only be declared inside Outer,
because there's no type name to declare anon with */
struct Inner {
int c;
} named;
/* this ^ struct could be declared outside, but why force it to be
different than the anonymous one? */
struct Related {
double d;
};
/* oh no we have no member declared immediately ... should we force this
declaration to be outside Outer now? */
struct Inner * (*function_pointer)(struct Related *);
/* no member but we are using it, now can it come back inside? */
struct Related excuse;
/* how about now? */
};
一旦允許這樣的嵌套類型聲明,我懷疑是否有任何特殊動機要求立即有該類型的成員。
這樣做是合法的(但風格極其糟糕):
struct A {
int a;
struct B {
int c;
};
};
struct B B_instance;
struct A A_instance;
而且編譯器不知道使用結構類型的更高版本的變量,因此它實際上不應出錯。
通常,警告表示該代碼可能未達到您的預期目的,但在該語言中是合法的。 編譯器說:“這可能不是您真正想做的,但是我必須允許您這樣做,因為該語言表明它是允許的。”編譯器無法為您提供此代碼的錯誤,因為C標准允許這樣做,因此必須予以允許(除非您明確要求此類錯誤,例如使用GCC的-Werror選項將警告變為錯誤)。
C標准不會嘗試定義程序中有意義的所有內容。 例如,這些在C語言中是合法的:
3;
if (x) then foo(); else foo();
x = 4*0;
第一條語句沒有副作用,並且不使用其返回值。 但這在C語言中是合法的,因為語句可能只是一個表達。 第二條語句僅調用foo()
,因此if
是毫無意義的。 在第三條語句中,乘以四是沒有意義的。
編寫一個禁止所有無意義的C標准非常困難。 這當然不值得付出努力。 因此,這就是您的答案的一部分:當編寫C標准的委員會構建該語言時,他們是否想花費大量時間重寫技術規范以排除不合理的內容? 有時是的,如果避免某些可能導致嚴重錯誤的事情似乎很有價值。 但是在很多時候,這是不值得的,並且會使規范變得不必要。
但是,編譯器可以識別其中的某些內容並警告您。 這有助於捕獲許多印刷錯誤或其他錯誤。
另一方面,有時這些構造是由異常情況引起的。 例如,一個程序可能具有預處理器語句,這些語句在為不同的目標或不同的功能構建時以不同的方式定義struct A
在某些目標中,可能是struct A
不需要struct B
成員,因此未聲明它,但是struct B
的聲明(類型,不是對象)仍然存在,只是因為它更易於編寫預處理器語句就是這樣。
因此,編譯器需要允許這些事情,以避免干擾編寫各種程序的程序員。
實際上,您在這里聲明了struct B
,但您沒有在聲明該類型的變量。
這是一個警告,但您應解決此警告。 也許您的意思是:
struct A
{ int a;
struct B
{
int c;
} c;
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.