• ベストアンサー

#ヘッダーファイルの2重インクルード防止コードについて

「ローベルのC++入門講座」という本を読んでいるのですが、 その中でヘッダーファイルの2重インクルードを回避するマクロとして、 ---------------------------------------------------------------- #ifndef REDEF1_H_20070101_1138_JOIE93UL_INCLUDED_ #define REDEF1_H_20070101_1138_JOIE93UL_INCLUDED_ const int N = 10; ・ ・ ・ #endif ---------------------------------------------------------------- というサンプルがでてくるのですが、 「REDEF1_H_20070101_1138_JOIE93UL_INCLUDED_」 の意味がよくわからないです。 おそらく、 「REDEF1_H」はファイル名で、 「20070101_1138」はredef1.hの作成日時か更新日時で 「INCLUDED」は「インクルードされている」の意味だと思う のですが、 「JOIE93UL」が何を意味するのかがさっぱりです。 さほど重要なことではなさそうですが、なんだか気持ちが悪いので どなたか教えて頂ければ幸いです

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

識別子名は、実は「重複さえしなければ、何でもOK」なのです。 #define SUZUMIYA_HARUHI_DAISUKI でも #define HARUHI_KAWAIIYO_HARUHI でも、何でも構いません。 ですが「適当に決めると、別のファイルの定義と衝突する可能性がある」ので「ファイル名や作成日を入れるなど、適当に決めても、他と重複する確率がゼロに近くなる」ようにします。 ですので >「REDEF1_H」はファイル名で、 >「20070101_1138」はredef1.hの作成日時か更新日時で >「INCLUDED」は「インクルードされている」の意味だと思う の部分は「適当に決めても他と重複しないようにする為」に、こうなっているだけなのです。 つまり、この部分は「ある規則に従って付けたので、なんか意味ありげだけど、実は意味は無い」のです。 でも、これだけでは「同じファイル名で、同じ時刻に、別の人が、別のヘッダーファイルを作る可能性」がゼロじゃないです。 そこで「他と絶対に重複しないようにする決定打」として「書いた本人だけしか意味が判らない文字列」も追加したのでしょう。 それが >「JOIE93UL」が何を意味するのかがさっぱりです。 です。 「書いた本人だけしか意味が判らない文字列」ならば「他人が同じ文字列を使う事は無い」ので、結果的に「他と絶対に重複しない」でしょう。 そう言う訳で「JOIE93UL」の意味を知ってるのは書いた本人だけで、貴方やここの回答者は、その意味が判らなくて当然です。 そして「それが何を意味するのか知っても、何の影響もない」ので、貴方がそれを知る必要はありません。 貴方が「SUZUMIYA_HARUHI_DAISUKI」の意味が判らなくたって、ちゃんとコンパイルできれば何の問題もありませんよね?つまり、そういうことです。

apraxas
質問者

お礼

ご回答ありがとうございます。 よりわかりやすい説明をして頂けて モヤモヤしたものが解消されました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

> __ファイル名 みたいな感じにしますが C言語ではアンダーバーで始まる識別子は、 規格や処理系が使用する、「予約済み識別子」に 指定されているので、これを使用した識別子は 規格上その動作が未定義になります。 #現存する殆どの処理系では問題ないでしょうが、 #わざわざつける物でもないと思います。 > 「JOIE93UL」が何を意味するのかがさっぱりです。 書いた人に聞いてください。 No2の人が書いているように、 重複していなければなんでも良いので、 何を意図して書いたかは、書いた人にしかわからないです。

apraxas
質問者

お礼

ご回答ありがとうございます。 低次元の質問にもかかわらず 丁寧にお答え頂いて感謝感激です。

全文を見る
すると、全ての回答が全文表示されます。
  • pick52
  • ベストアンサー率35% (166/466)
回答No.1

これは単なる例であり、同一プロジェクト内で重複しないなら何でも かまいません。 通常は、 __ファイル名 みたいな感じにしますが特に決まりがあるわけ ではありません。 ただし同じプロジェクト内では共通のルールで指定した方がいいでしょう。 #ifndef は指定された名前のマクロ(#define で登録した別名)が なければ #endif までを実行するプリプロセッサ(ディレクティブ)です。

参考URL:
http://www11.plala.or.jp/studyhall/cpp/include.html
apraxas
質問者

お礼

ご回答ありがとうございます。 何らかの書式に対応した書き方だと思っていたのが 誤りだったわけですね。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • #ifndefとかヘッダファイルについて

    http://www.geocities.co.jp/SiliconValley/6071/technic/16.html に書いてあることで質問です。 /* myheader.h */ #ifndef __myheader_H__ #define __myheader_H__ : : : #endif と記述されているのですが、ここの「#define __myheader_H__ 」というのは、myheader.hをインクルードしているという意味になるのでしょうか? あと、ifndef等でヘッダファイルが読み込まれているか判定する際には、コンマをアンダーバー(アンダースコア)に変えるという作業は必ずいるようですが、いろんな所を調べてみると、例えば、myheader.hについて判定する場合は、 __myheader_H__ myheader_H _myheader_H _MYHEADER_H 等、アンダースコアが先頭と最後に2個付いていたり、先頭に1個だけだったり、全部大文字にしていたりと、様々なものがあるのですが、これはどの様な表記を使えばいいのでしょうか?

  • ヘッダファイルの2重のインクルードについて

    ある書物に「ヘッダファイルを複数回インクルードすると、それを”再定義”することによるエラーになる」と書いてありますたが、以下のようなヘッダファイルを作りそれを数回インクルードしても何ら異状が無くコンパイルできました。 math.h→ヘッダファイル名 #define max(a,b)  ((a)>(b)?(a):(b))→ヘッダファイルの内容 c ファイル #include<stdio.h> #include"math.h"←複数回インクルード #include"math.h"←複数回インクルード int main(void){ int x=1,y=2; printf("max(x,y)=%d\n",max(x,y)); return 0; } 環境としては、RedHat Linuxでviです。 何ゆえ、エラーにならないのか良く解りません。 宜しくお願いします。

  • VC++6.0でのインクルード

    VC++初心者です。 環境はVC++ on win2kなのですが、 ヘッダファイルを別のファイルにしてコンパイルしたいのですが、できません。 test.cppの中身 #include <iostream> #include <string> #include <stdio> ・・・* #include "kneko.h" using namespace std; int main() { kneko x("tama"); x.naku(); } kneko.hの中身 #ifndef __kneko_h #define __kneko_h class kneko { string name; public: kneko(){}; kneko(string n){ name=n; } void setname(string n){ name=n; } void naku() const { cout <<"My name is"<<"name"<<"."endl; } }; #endif この2つを同じディレクトリに入れて、 ビルド→コンパイルすると、*のところで 「インクルードファイルがオープンできません。」 というエラーが出ます。 ためしに*の行を削除すると、エラーが8つぐらい出てきます。 どうやらヘッダファイルを読み込めていないようです。 インクルードの書式が間違っているのでしょうか?

  • 関数の実体定義にヘッダファイルの2重定義防止方法が効かない?

    いつもお世話になっています。 MFCでCプログラミングをしています。 ヘッダファイルの2重定義防止のために、 ヘッダファイル全体を下記のように 囲みました。 <aaa.h> #ifndef AAA #define AAA #define PI 3.141592 void Func(); int wa(int a, int b){ return a+b; } #endif ビルドしたところ、 関数宣言(Func)や#define部分(PI)については、 2重定義が防止されているようなのですが、 関数の実体部分(関数wa)については、 2重定義防止機能が働かず、 ***.obj : error LNK2005: "int __cdecl wa(int a, int b)" は既に ***.obj で定義されています。 というリンクエラーが表示されます。 関数の種類や ヘッダファイル内の宣言の順番を いろいろ変えてみたのですが同じ結果でした。 ここで、このヘッダファイルの先頭に #pragma onceを使用すると このリンクエラーは回避されるのですが、 他コンパイラとの互換性の観点から、 #pragma once以外の方法で実現する必要があるので、 困っています。 URLを検索してみたのですが、 このような特殊な場合について記述されているものは 見つけられませんでした。 どなたか解決法又はヒントをご教示頂ければ ありがたいです。 よろしくお願いします。

  • ヘッダーファイルがインクルードされない(?)

    ダイアログ上のボタンをクリックすると指定されたテキストファイルをオープンし、 ファイルの内容をスペースで区切って格納するプログラムを http://oshiete1.goo.ne.jp/kotaeru.php3?q=474452 こちらを少し変えて作ったのですが、 コンパイル・デバッグを行なうと 'std' : 識別子がクラス名でも名前空間名でもありません。 'vector' : 定義されていない識別子です。 'ofstream' : 定義されていない識別子です。 と言ったようなエラーになってしまいます。 必要なヘッダーファイルはインクルードされているはずなのですが・・・。 この原因は何故でしょうか? /**********プログラムソース**********/ #include <iostream> #include <fstream> #include <string> #include <vector> #include <utility> #include "stdafx.h" #include "SCHEDULE.h" #include "SCHEDULEDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // ~中略~ void CSCHEDULEDlg::OnReq() {    typedef std::pair<std::string,std::string> item;    std::vector<item> participation;    std::ofstream file(dataFile.txt);    std::string line;    while ( std::getline(file,line) ) {      std::string::size_type pos = line.find(' ');      participation.push_back(item(line.substr(0,pos), line.substr(pos+1)));    }    for ( int i = 0; i < participation.size(); ++ i) {      std::cout << "result = " << participation[j] << "]\n";    } }

  • C言語でヘッダファイルを自作する

    C言語で#defineを用いてヘッダファイルを作成したのですが、 作成したコンパイルするときにヘッダファイルがオープンできません。 参考にしている資料があるのですが、そこに書かれているサンプルプログラムを 丸ごとコピーして作ったプログラムも同様にヘッダファイルがオープンできない というエラーが出るので、ヘッダファイルを定義する方法そのものが間違っていると 思うのですが、どこが間違っているのでしょうか? よろしければ正しい記述方法もお教えください。 #include <stdio.h> #if !defined SAMPLE_H #define SAMPLE_H wa(int a, int b) { return a+b; } #endif #include "sample.h" int main(){ printf("%d\n",wa(40,70)); return 0; } ヘッダファイルの定義の方法は他にもあるとは思いますが、 今回は#defineを用いた方法でお願いします。

  • ヘッダーファイルのインクルード

    VC++6.0です。 ヘッダーファイルをincludeしていいかどうかは どのように決まるのでしょうか? classは、appとhogeの1種類があるとして、 app.h、app.cppとhoge.cpp、hoge.hの4つのファイルがあるとします。 1)appによるhogeのメンバの操作があって、その逆は無い場合 2)hogeもappのメンバを操作する場合 のそれぞれで教えてください。 最初、私は、そのclass内で別のclassのメンバ関数を 呼ぼうと呼ぶまいとincludeしてもかまわないと思っていました。 しかし、自分の作ったプログラムを検討したところ 1)の場合で、hogeのヘッダーに #include "app.h"と入れるとエラーになります。 hogeのcppファイルに#include "app.h"と入れてもエラーになります。

  • DirectX開発中のinclude ファイルを開けません。

    DirectX開発中に c:\documents and settings\a022\my documents\visual studio 2008\projects\map\map\stdafx.h(10) : fatal error C1083: include ファイルを開けません。'WinLib.h': No such file or directory MapModel.cpp 上のソースコードは、 #ifdef _MSC_VER // 警告の抑制 #pragma warning(disable: 4201) #pragma warning(disable: 4100) #pragma warning(disable: 4786) #endif #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x400 #endif #include <WinLib.h> ←ここがよめないらしい というエラーが出ます。 解決法がわかる方はお教えください。

  • 自作したヘッダファイルをインクルードするには

    自作したヘッダファイルをインクルードするには 自作したヘッダファイルを半角スペースを含むフォルダを指定する時、 何かエスケープシーケンス文字が必要でしたでしょうか?ド忘れしてしまいました… 例えば、Program Filesの直下に入れた自作ヘッダファイルa.h(まず考えられないとは思いますが…)を インクルードしたい時、 #include "C:\\Program Files\\a.h" でいいんですよね?

  • なぜ、C++の標準ヘッダをインクルードするとき拡張子をつけないのか。

    なぜ、C++の標準ヘッダをインクルードするとき拡張子をつけないのか。 そもそもiostreamなどは拡張子をもっているのですか? 拡張子はあるけれどインクルードするときに付けてないだけとか?だとしたら、同じファイル名で拡張子の違いで判別できないですよね?a.hとa.hppがあったら#include <a>じゃわからないって意味。 自分でヘッダーファイルを作る場合はどのようにすればいいのでしょうか? 自分で作ったヘッダーファイルも標準ヘッダの様に拡張子を付けないでインクルードすることができますか?そういった事はするべきではないのでしょうか? この拡張子をつけないというのはC++の標準ヘッダだけ特別仕様とか? Cと同じように.hでヘッダーファイル作って#include "a.h"とかにしておけばいいのかなー?? 詳しい方、わかりやすく説明して頂けないでしょうか。よろしくお願いします。