11

#pragma onceインクルード ガードの外側と内側の配置に違いはありますか?

ケース 1:

#ifndef SOME_HEADER_H
#define SOME_HEADER_H
#pragma once

ケース 2:

#pragma once
#ifndef SOME_HEADER_H
#define SOME_HEADER_H

コードで両方(プラグマとヘッダーガード)を組み合わせることにしたので、どちらか一方(ケース1またはケース2)を好む特別なケースがあるかどうか、好奇心から思っています。

編集:

皆さんは私の質問を誤解していると思います...pragma onceプラグマワンス対ヘッダーガードではなく、の場所について質問しています。

4

3 に答える 3

7

SOME_HEADER_Hヘッダーがインクルードされる前に if が既に定義されている場合、2 番目のケースではプリプロセッサが を処理#pragma onceし、最初のケースでは処理しないという微妙な違いがあります。

#undef SOME_HEADER_H同じ TU でファイルを再度インクルードすると、機能的な違いが見られます。

#define SOME_HEADER_H
#include "some_header.h"
#undef SOME_HEADER_H
#include "some_header.h"

さて、ケース 1 では、ヘッダー ファイルからのすべての定義があります。ケース2ではありません。

がなくても、ケース 1 で が無視される#undefため、前処理時間に違いが見られる可能性があります。それは実装次第です。#pragma once

このヘッダー ファイルを最初にインクルードする前に、既に定義されている 2 つのもっともらしい方法を考えることができます。

  • (明らかなもの)完全に別のファイルが、意図的に、または偶然の名前の衝突によってそれを定義します。
  • このファイルのコピーはすでに定義されています。実装によっては、このファイルが 2 つの異なるファイル名で同じ TU に含まれる場合が含まれる場合があります。たとえば、シンボリック リンクまたはファイル システムのマージが原因です。実装が をサポートしていて#pragma once、そのドキュメントを注意深く調べると、最適化がファイルが含まれるパスによって適用されるのか、それとも inode などのファイルのストレージを識別する何かの比較によって適用されるのか、決定的なステートメントを見つけることができる場合があります。番号。後者の場合、「本当に同じファイル」であることを隠すためにローカルファイルシステムをリモートマウントするなど、プリプロセッサをだますために引き出される可能性のある詐欺がまだあるかどうかを突き止めることさえできるかもしれません...

#pragma onceただし、期待どおりに使用しても、 Microsoft が定義した方法で実装が処理される限り、違いはありません。スキップされるのではなく処理される限り、含まれているファイルが最適化のためにマークされるため、ファイルの 2 番目のパスで処理されるかどうかは問題ではありません。2 番目のパスは発生しません。

もちろん、プラグマは非標準であるため、少なくとも理論的には、実装が異なるとまったく異なる意味を持つ可能性があり、その場合、いつ、何回処理されるかが問題になる可能性があります。実際には、誰もそれをしないと思うでしょう。

于 2011-03-21T22:23:28.623 に答える
6

それらは冗長です。

#pragma onceインクルードガードはサポートされていますが、すべてのコンパイラでサポートされているわけではありません。インクルードガードを使用するだけです。gccのようなコンパイラは、インクルードガードを理解するのに十分賢く、ファイルを再度開くことさえしません。

于 2011-03-21T19:17:02.513 に答える
1

あなたの質問に答えるには:

ケース1:

コンパイラは、プリプロセッサ定数が設定されているかどうかを確認し、設定されていない場合は、#pragmaońceディレクティブを確認します。これは、文字列 "SOME_HEADER_H"のハッシュルックアップであり、現在のファイル名(おそらくプリプロセッサによって設定された__ FILE __定数)で別のハッシュルックアップを実行する前に、定義されているかどうかを確認します。したがって、ファイルが一度も読み取られていない場合は、2つのハッシュルックアップと2つのハッシュ保存があり、ファイルが1回のハッシュルックアップだけで読み取られている場合です。

ケース2:

これは明らかにケース1と同じですが、順序が逆です。したがって、比較できるのは、ルックアップとして使用するハッシュキーの長さだけです。現在のヘッダーファイルへのパス、つまりパスの長さによっては、#pragmaonceディレクティブのハッシュルックアップの計算にコストがかかる場合があります。ファイル名が「C:\ dude.h」の場合、「SOME_HEADER_H」よりも短くなります。

要約すると、私は推測します。いいえ。ケース1がケース2よりも有益である、またはその逆の特別なケースはありません。少なくともHeurekaを怒鳴らないでください;)

乾杯

于 2011-03-21T21:32:02.607 に答える