2013-11-24 68 views
1

如果我做了以下內容:包括逆天的#ifndef的#define語句預處理

dConst.hpp

const int POWER_LEVEL = 9001; 

genPower.hpp

#include "dConst.hpp" 

#ifndef GENPOWER_HPP 
#define GENPOWER_HPP 

const int GENERATOR[1] = { POWER_LEVEL }; 

#endif 

我結束對於任何使用該生成代碼的代碼都會收到鏈接器錯誤數組常量。

但是,如果我切換#include "dConst.hpp"的代碼塊:

#ifndef GENPOWER_HPP 
#define GENPOWER_HPP 

它的工作原理...

我是否濫用#ifndef的力量?

+0

這是有效的* const *聲明在C++中有內部鏈接。包含警衛不應該禁止鏈接器錯誤。什麼編譯器/鏈接器產生這個錯誤?鏈接器錯誤實際上是什麼樣的? –

+0

@HansPassant我碰巧在當時使用Visual Studio 2012編譯器/鏈接器 –

回答

1

你是使用不足 #ifndef的威力。您的dConst.hpp文件需要包括警衛。否則,如果它包含在翻譯單元中的多個文件中,將會導致問題(您看到確切的問題)。

編輯:我也會把你的包括警衛genPower.hpp在你的包含語句之前的文件的頂部。

1

是的,絕對。

包含守衛點是要確保你的代碼不會被包含兩次 - 如果你的頭文件中有一些不在包含守護進程內的代碼,如果你包含了兩次這個頭文件,外面的警衛兩次。

對於有些更好的想法是怎麼回事,生成的代碼看起來是這樣的:

中的#include基本上只是插入包含文件的內容直接導入到位等文件,這意味着您genPower.hpp看起來像這樣(沒有到位包括警衛正確,就像你在你的問題有原):

const int POWER_LEVEL = 9001; 

#ifndef GENPOWER_HPP 
#define GENPOWER_HPP 

const int GENERATOR[1] = { POWER_LEVEL }; 

#endif 

因此,每次你包含這個文件時,得到的#ifndef達到之前,POWER_LEVEL得到定義。如果您使用#ifndef/#define切換POWER_LEVEL行,每次包含此文件時,它都會首先檢查它是否已包含在內(使用#ifndef - 如果它已被包含,則#define應該已完成其工作)並且只有這樣(一旦發現這是第一次),它會定義POWER_LEVEL。另外,你幾乎肯定希望在你的dConst.hpp中包含警衛 - 所有頭文件都應該包含守衛,並且他們應該在頭文件中保護所有東西。這是#ifndef的錯誤。