ヘッダファイルの複数含む

2439 ワード

#includeファイルの1つの不利な点は、1つのヘッダファイルが複数回含まれる可能性があることであり、このエラーを説明するために、#include“a.h”#include“b.h”は、a.hおよびb.hの両方に1つのヘッダファイルx.hが含まれている場合である.ではx.hはここでも同様に2回含まれていますが、その形式はそれほど明らかではありません.複数の組み込みは、ほとんどの場合、大規模なプログラムで発生します.多くのヘッダファイルを使用する必要があるため、重複する組み込みを発見するのは容易ではありません.
同じファイルがincludeで複数回行われることを避けるために、C/C++には2つの方式があり、1つは#ifndef方式、1つは#pragma once方式である.この2つの方式をサポートできるコンパイラでは、両者には大きな違いはありませんが、両者にはまだ細かい違いがあります.方法一:#ifndef_SOMEFILE_H__  #define __SOMEFILE_H__  ... ...//宣言、定義文#endifプリプロセッサは、このヘッダファイルのすべての内容が無視されても、ヘッダファイル全体を読み込むことを覚えておく必要があります.この処理はコンパイル速度を遅くするので、可能であれば多重含むことを避けるべきである.重複する組み込みはネストされた組み込みを引き起こす可能性があります.ネストされた組み込み階層が深すぎると、コンパイルエラーが発生します.標準では、コンパイラが少なくとも8層のヘッダファイルのネストをサポートする必要があります.実際には、#include命令のネスト深さを1層または2層以上にする理由はありません.方法2:#pragma once......//文#ifndefを宣言、定義する方法はC/C++言語標準でサポートされています.同じファイルが複数回含まれないことを保証するだけでなく、内容が完全に同じ2つのファイル(またはコードクリップ)が不注意で同時に含まれないことを保証します.もちろん、欠点は、異なるヘッダファイルのマクロ名がうっかり「衝突」すると、ヘッダファイルが存在しているのに、コンパイラが声明が見つからないと言い張ることになる可能性があります.このような状況は、非常に気が狂うことがあります.コンパイラは、繰り返し定義があるかどうかを判定するためにヘッダファイルを開く必要があるため、ifndefをコンパイルするとコンパイル時間が比較的長くなるため、pragma once方式をサポートし始めるコンパイラもあります.#pragma onceは一般的にコンパイラによって保証されます.同じファイルが複数回含まれないことを保証します.なお、ここでいう「同じファイル」とは、同じ内容の2つのファイルではなく、物理的に1つのファイルを指す.ヘッダファイルのコードの一部をpragma onceで宣言することはできませんが、ファイルのみに対して宣言できます.その利点は、マクロ名を考えるのに苦労する必要がなく、マクロ名の衝突による奇妙な問題も発生しないことです.大規模なプロジェクトのコンパイル速度も向上しました.対応する欠点は,あるヘッダファイルに複数のコピーがある場合,本手法が重複して含まれないことを保証できないことである.もちろん、マクロ名の衝突による「宣言が見つからない」という問題に比べて、この重複は発見され、修正されやすい.#pragma once方式は#ifndef以降に発生するため、多くの人が聞いたことがないかもしれません.現在のところ、ifndefはさらに推奨されている.#ifndefはC/C++言語標準によってサポートされているため、コンパイラの制限を受けません.一方、pragma once方式は古いバージョンのコンパイラではサポートされておらず、サポートされているコンパイラの中には削除しようとしているものもあるので、互換性が悪いかもしれません.一般的に、プログラマーはこのような話を聞くと、#ifndef方式を選択し、自分のコードをより長く「生存」させるために努力し、通常はコンパイル性能を低下させたほうがいい.これはプログラマーの個性であり、もちろんこれは余談である.両者を一緒に置く方法も見られます:#pragma once#ifndef_SOMEFILE_H__  #define __SOMEFILE_H__  ... ...//宣言、定義文#endifは、両者の利点を兼ね備えたいように見えます.しかし、#ifndefを使用するとマクロ名が衝突する危険もあり、#pragma onceをサポートしないコンパイラのエラーも避けられないため、2つの方法を混用することはより多くのメリットをもたらすことはできないようで、慣れない人を困惑させることになります.どちらの方式を選ぶかは、2つの方式を知る場合、具体的な状況によって異なります.欠点を避けるための合理的な約束さえあれば、どんな方法でも受け入れられると思います.これは標準やコンパイラの責任ではなく、プログラマー自身や小規模な開発規範によって解決されるべきだ.btw:GNUのいくつかの議論を見て、GCC 3.4(それ以降?)のバージョンで#pragma onceのサポートがキャンセルされました.しかし、実際には、私の手にあるGCC 3.4.2とGCC 4.1.1は依然として#pragma onceをサポートしています.deprecation warningもありません.GCC 2です.95は#pragma onceにwarningを提出します.VC 6以降もpragma once方式のサポートを提供しており、この特性はほぼ安定しているはずです.
ネストされた重複を最小限に抑えるための合理的な計画