簡體   English   中英

目標#ifndef FILENAME ...#endif在頭文件中

[英]Purpose of #ifndef FILENAME…#endif in header file

我知道它可以防止多次包含頭文件。 但是假設我確保只在一個.cpp文件中包含此文件一次。 是否還有我需要這種安全防范的情況?

不,這是包含警衛的唯一目的,但使用它們應該是一個明智的選擇:這樣做需要的時間很少,可能會節省很多。

您可以保證您的代碼只包含一次,但是您能保證任何人的代碼都包含一次嗎?

此外,想象一下:

// a.h
typedef struct { int x; int y; } type1;

// b.h
#include "a.h"
typedef struct { type1 old; int z; } type2;

// main.c
#include "a.h"
#include "b.h"

不好了! 我們main.c只包括每一次,但bh包含ah ,所以我們得到了ah ,盡管我們盡了最大努力,兩次。

現在想象這隱藏在三層或更多層的#include s之后,它是一個小的內部使用專用頭,它被包含兩次,這是一個問題,因為其中一個頭#undef編了一個它定義的宏,但是第二個頭#define它再次打破了一些代碼,需要花費幾個小時來弄清楚為什么存在相互矛盾的定義。

這是它唯一的存在理由。 即使你認為你有這個問題,這仍然是一個好主意; 它不會減慢你的代碼速度或任何東西,並且永遠不會傷害到額外的防守。

保護的目的是為了防止文件被重新列入同一.cpp文件不止一次。 它不能防止將文件包含在多個.cpp文件中。

如果您確定頭文件未包含在另一個頭文件中,則不需要保護。 但它還是很好的形式。

甚至更好的形式是使用

#pragma once

如果您的編譯器支持它。

確保您的代碼只包含一次是所謂的“標題保護”的唯一目的。

這可能很有用,好像在您的頭文件之間存在循環依賴關系,您不會陷入包含文件的無限循環中。

我能想到的另一個場景(我們做到了)是創建C ++模擬。

您在構建中明確定義了文件GUARD值,然后您可以通過-include my_mock.h作為附加編譯器選項(我們使用g ++)添加您自己的模擬實現。

my_mock.h

#define THAT_FILE_GUARD

class ThatClass 
{
  void connect() 
  {
     std::cout << "mock connect" << std::endl;
  }
}

使用像這樣的頭文件加速編譯過程,想象有三個源文件使用頭(減去頭部保護),這反過來意味着編譯器必須多次包括頭(解析和lexing語法) 。

有了一個標題保護,編譯器會說'哈! 我以前見過這個,並且我不會解析/ lex語法'從而加快編譯過程。

希望這會有所幫助,最好的問候,湯姆。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM