2012-07-11 51 views
2

我在一個示範項目文件iforce2d_topdown_car.h與包括防護件,像這樣:具有重複的警告包括在Objective-C後衛C++頭

#ifndef IFORCE2D_TOPDOWN_CAR_H 
#define IFORCE2D_TOPDOWN_CAR_H 

... source code ... 

#endif 

這被包括在HelloWorldLayer.h,這是然後包含在其他兩個文件中(除iforce2d頭之外,這些文件都是obj-c)。一切都編譯好,但我得到的任何錯誤顯示3次。這讓我很煩惱,我不知道它是否是一個更大問題的症狀。

Header funkiness in xcode

這是預期的行爲?在我看來,如果一個預處理器var被定義了,那麼它將保持定義,下一次被包含它將不會被編譯。看來情況並非如此,但我不知道爲什麼。

回答

2

TDCar(b2World *)是一個內聯成員函數,因爲它是在其類定義中定義的。這意味着編譯器實例化函數並在調用此函數的每個翻譯單元中發出相應的警告。

讓我們想象一下,你有以下A.h

class A { 
public: 
    int f(int i); 
};

A.cpp

int A::f(int i) { 
    int j = i; 
    return i + 1; 
}

編譯;功能A::f(int i)一次,導出所以該函數每次調用將鏈接到出口符號。因此,未使用變量j的警告將會發出一次:編譯A.cpp時。

但如果你用以下A.h

class A { 
public: 
    int f(int i) { 
     int j = i; 
     return i + 1; 
    } 
};

編譯器會從函數定義的代碼直接複製到調用該函數的源代碼文件。如果您在3個不同的文件中使用該函數,則該函數將被編譯三次,並且警告將發出三次。

由於每個文件都是單獨編譯的,因此編譯器無法知道已經爲其他文件發出警告。

Xcode應該足夠聰明,以識別三個警告是相同的,並聚合它們,所以你只能得到一個警告。不幸的是,Xcode並不聰明。

+0

嗨尼古拉斯,謝謝你的回答。你已經澄清了一下發生了什麼,但是我仍然對包含後衛如何避免編譯多次的代碼感到困惑。不應該只運行一次#define,然後接下來的兩次它不應該被編譯? – 2012-07-11 18:08:29

+0

包含的守護程序在同一個翻譯單元**中只保留一次**以上的代碼。如果幾個源文件包含相同的頭文件,他們都需要獲取它的內容。 – 2012-07-11 18:12:17

+0

啊哈!感謝那!看起來這是不尋常的,因爲原始編碼器在標題內使用了代碼。我會盡量不要用我自己的代碼來做到這一點。 – 2012-07-11 18:24:27