[英]Using preprocessor #ifdef on a class field
此類是在我的項目中定義的:
class B : public A
{
public:
A& Get_a(int type);
...
protected:
#ifdef COMPILE_FLAG
int line_num;
const char* file_name;
#endif
...
private:
int int_value;
bool bool-val;
};
函數Get_a
是這樣實現的(我只Get_a
了相關部分):
A& B::Get_a(int type)
{
B* returned_a = B->Get_val(type);
return *(A*)(returned_a) ;
}
這是我使用此類的代碼:
{
...
B b_val;
A* a_val = &b_val->Get_a(5);
...
}
我的代碼被編譯到與A和B類被編譯到的DLL不同的DLL。 我的DLL不使用標志COMPILE_FLAG進行編譯,但是A,B的DLL確實使用該標志進行編譯。 即使我的代碼嘗試從不同的B類進行轉換,我也沒有遇到任何編譯錯誤。 在我的代碼執行期間, a_val
具有垃圾字段值; 實際轉移了價值。
我想對C ++編譯器為什么沒有從此錯誤中發出警告的解釋,以及如何改進這些#ifdef
定義的編碼技巧(我被告知這些字段用於記錄日志)。
編輯:如果我要編寫2個具有相同名稱的類,則每個類都在不同的dll中。 然后,如果我要在它們之間創建引用,則會出現編譯錯誤。 前處理器在編譯器之前運行,因此編譯器可以檢查對類的重新定義。
我想對為什么C ++編譯器沒有從此錯誤警告我的一些解釋
編譯器應如何警告您? 您編譯了兩個具有不同選項的不同集合。 由於類定義更改,由於這些標志,每個二進制文件中的內存布局都不同。 但是編譯器怎么知道呢?
編譯不同版本是一個非常有效的方案,正確使用它們取決於程序員/用戶。
因此,如果要互相傳遞其他定義,則必須將所有DLL重新編譯為相同版本。
#ifdef
是預處理程序指令。 預處理作為編譯的第一部分執行。 僅在預處理后,正常的C ++語法才必須有效並可以進行檢查。
使用#ifdef
違反了一個定義規則 :在不同的翻譯單元中,有兩個不同的B
類定義(大小不同)。 編譯器無法檢測到這一點。 作為結論,我會說這是您代碼中的錯誤。 作為編碼技巧,我建議使用相同的編譯器設置來編譯所有文件。 在這種情況下,我將刪除#ifdef
。
#ifdef
不會改變您使用它的位置。 如果COMPILE_FLAG
(如#define COMPILE_FLAG
則該塊將不會編譯。 因此,您不能使用這些變量(line_num,file_name),如果使用它們,您將得到。 這兩行被完全忽略。 因此,您還必須將使用這些變量的代碼也放入#ifdef
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.