C 中避免同一檔案被多次引用解決方案

2021-05-21 20:17:44 字數 1556 閱讀 4056

為了避 免同乙個檔案被include多次,c/c++中有兩種方式,一種是#ifndef方式, 一種是#pragma once方式。在能夠支援這兩種方式的編譯器上,二者並沒有 太大的區別,但是兩者仍然還是有一些細微的區別。

方式一:

#ifndef __somefile_h__

#define __somefile_h__

... ... // 宣告、定義語句

#endif

方式二:

#pragma once

... ... // 宣告、定義語句

#ifndef的方式受c/c++語言標準支援。它不光可以 保證同乙個檔案不會被包含多次,也能保證內容完全相同的兩個檔案(或者 **片段)不會被不小心同時包含。

當然,缺點就是如果不同標頭檔案中的巨集名不小心 「撞車」,可能就會導致你看到標頭檔案明明存在,編譯器卻硬說 找不到宣告的狀況——這種情況有時非常讓人抓狂。

由於編譯器每次都需要開啟標頭檔案才能判定是否有重 復定義,因此在編譯大型專案時,ifndef會使得編譯時間相對較長,因此一 些編譯器逐漸開始支援#pragma once的方式。

對應的缺點就是如果某個標頭檔案有多份拷貝,本方法 不能保證他們不被重複包含。當然,相比巨集名碰撞引發的「找不到聲 明」的問題,這種重複包含很容易被發現並修正。

#pragma once方式產生於#ifndef之後,因此很多 人可能甚至沒有聽說過。目前看來#ifndef更受到推崇。因為#ifndef受 c/c++語言標準的支援,不受編譯器的任何限制;而#pragma once方式卻不 受一些較老版本的編譯器支援,一些支援了的編譯器又打算去掉它,所以它 的相容性可能不夠好。一般而言,當程式設計師聽到這樣的話,都會選擇 #ifndef方式,為了努力使得自己的**「存活」時間更久,通 常寧願降低一些編譯效能,這是程式設計師的個性,當然這是題外話啦。

還看到一種用法是把兩者放在一起的:

#pragma once

#ifndef __somefile_h__

#define __somefile_h__

... ... // 宣告、定義語句

#endif

看起來似乎是想兼有兩者的優點。不過只要使用了 #ifndef就會有巨集名衝突的危險,也無法避免不支援#pragma once的編譯器 報錯,所以混用兩種方法似乎不能帶來更多的好處,倒是會讓一些不熟悉的 人感到困惑。

選擇哪種方式,應該在了解兩種方式的情況下,視 具體情況而定。只要有乙個合理的約定來避開缺點,我認為哪種方式都是可 以接受的。而這個已經不是標準或者編譯器的責任了,應當由程式設計師自己或 者小範圍內的開發規範來搞定。

btw:我看到gnu的一些討論似乎是打算在gcc 3.4 (及其以後?)的版本取消對#pragma once的支援。不過事實上,我手上的 gcc 3.4.2和gcc 4.1.1仍然支援#pragma once,甚至沒有deprecation warning,倒是gcc2.95會對#pragma once提出warning。

vc6及其以後版本亦提供對#pragma once方式的支援, 這一特性應該基本穩定下來了。 

tag標籤:

pragma once,

ifndef,

標頭檔案,

重複,包含

避免同乙個檔案被include多次

我們知道c 有時會遇到防止標頭檔案重複include問題,常用的方式可以防止.h檔案重複include 的方式為 if defined.define.但是在有些地方發現了這段 if msc ver 1000 pragma once endif msc ver 1000 查了一下也是防止重複inclu...

避免同乙個檔案被include多次

1 ifndef方式 2 pragma once方式 在能夠支援這兩種方式的編譯器上,二者並沒有太大的區別,但是兩者仍然還是有一些細微的區別。方式一 ifndef somefile h define somefile h 一些宣告語句 endif 方式二 pragma once 一些宣告語句 ifn...

引用另一檔案的變數

在微控制器的程式設計中,為了自己下次開啟程式或將程式交給小夥伴時能對程式一目了然,我們通常會分成很多個檔案寫程式,每個檔案只寫對乙個外設執行的函式。但也因此我們很多時候都需要從另乙個檔案中引用變數,使得多個外設協同工作。那麼該怎麼引用呢?首先,我們要在a.c定義乙個變數,然後在a.h宣告,最後b.c...