C プラグマ 新しいページはコチラ
提供: yonewiki
(→#pragma comment(linker, [” ”])) |
(→#pragma once) |
||
1行: | 1行: | ||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る | ||
+ | |||
+ | |||
※このページではC言語にも存在していたという意味で記事タイトルがC プラグマになっていますが、<br /> | ※このページではC言語にも存在していたという意味で記事タイトルがC プラグマになっていますが、<br /> | ||
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | [[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br /> | ||
18行: | 21行: | ||
=='''#pragma'''== | =='''#pragma'''== | ||
+ | |||
<nowiki>#</nowiki>pragmaディレクティブは半角スペースに続けてもう一つのワードと引数パラメータを伴って定義する形式のものがほとんどです。また、マイクロソフト固有の仕様ですが、<nowiki>#</nowiki>pragmaの代わりに__pragmaでも同様の機能として動作するようになっています。これはディレクティブとして先頭に使われる#以降の#はプリプロセッサ演算子の文字列化演算子として扱われることを回避するために用意されています。 | <nowiki>#</nowiki>pragmaディレクティブは半角スペースに続けてもう一つのワードと引数パラメータを伴って定義する形式のものがほとんどです。また、マイクロソフト固有の仕様ですが、<nowiki>#</nowiki>pragmaの代わりに__pragmaでも同様の機能として動作するようになっています。これはディレクティブとして先頭に使われる#以降の#はプリプロセッサ演算子の文字列化演算子として扱われることを回避するために用意されています。 | ||
110行: | 114行: | ||
があります。それぞれについても以下に説明します。 | があります。それぞれについても以下に説明します。 | ||
+ | |||
+ | |||
+ | |||
====#pragma comment(compiler)==== | ====#pragma comment(compiler)==== | ||
131行: | 138行: | ||
となるような、ASCIIコードが挿入されました。.objファイルはバイナリーファイルですので、ASCIIコードとして読み取れる部分とそうでない部分とが混在するファイルになっています。 | となるような、ASCIIコードが挿入されました。.objファイルはバイナリーファイルですので、ASCIIコードとして読み取れる部分とそうでない部分とが混在するファイルになっています。 | ||
+ | |||
+ | |||
+ | |||
====#pragma comment(linker, [” ”])==== | ====#pragma comment(linker, [” ”])==== | ||
173行: | 183行: | ||
リンク処理の解析は機械語を読み解くのと同様に複雑ですが、動作自体は簡単な処理だと言われています。なんだかよくわからない処理がなされているように思われがちなリンク処理ですが、法則を理解出来れば、もっと理解が深まるということだと思います。 | リンク処理の解析は機械語を読み解くのと同様に複雑ですが、動作自体は簡単な処理だと言われています。なんだかよくわからない処理がなされているように思われがちなリンク処理ですが、法則を理解出来れば、もっと理解が深まるということだと思います。 | ||
+ | |||
+ | |||
====#pragma comment(user, [” ”])==== | ====#pragma comment(user, [” ”])==== | ||
182行: | 194行: | ||
'''<nowiki>#</nowiki>pragma comment(user, ”コメント(ASCIIコード範囲の文字利用を推奨)”)''' | '''<nowiki>#</nowiki>pragma comment(user, ”コメント(ASCIIコード範囲の文字利用を推奨)”)''' | ||
+ | |||
+ | |||
+ | |||
+ | |||
===#pragma once=== | ===#pragma once=== | ||
+ | <nowiki>#</nowiki>includeのようなソース読み込み指示によって、ソースファイルが重複してオープンされないように制御するためのプラグマです。プロジェクトに使われるヘッダファイルとメインソースコードファイルの全てに追加しておくべきプラグマです。以下のマクロと同等だと考えてよいです。 | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | FILE sample.h | ||
+ | #ifndef __SAMPLE.H__ | ||
+ | #define __SAMPLE.H__ | ||
+ | |||
+ | ヘッダファイルプロトタイプ宣言 | ||
+ | |||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | 上記のようなマクロでは、インクルードガードと呼ばれる手法を使っていると呼ばれていて、一度ヘッダファイルを読み込むとファイル名ごとに決められたマクロ名が定義され、2回目にヘッダファイルが呼び出された時にはマクロが定義されているため、#ifndefの条件が成立せず、重複して読み込まれないようになります。 | ||
+ | |||
+ | |||
+ | 上記のようなインクルードガードを簡潔にするのが、#pragma onceです。処理系によってこのプラグマは使えないものもありますが、最近のコンパイラでは広く適用できるプラグマになっているので、汎用性が高まると思います。 | ||
+ | |||
+ | |||
+ | 上記マクロを以下のようにプラグマを使って、すっきりと記述できます。 | ||
+ | <syntaxhighlight lang="cpp"> | ||
+ | FILE sample.h | ||
+ | #pragma once | ||
+ | ヘッダファイルプロトタイプ宣言 | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | 但し、この方法は標準化されたものではないため、Microsoft Visual Studio C++ 4.0以上でしか動作しないと考えて扱っても良いのかもしれません。他のコンパイラでも動作するものもありますが、自分の環境に合わせてしまっても良いと思います。他の人に配るなら、 | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | FILE sample.h | ||
+ | #ifndef __SAMPLE.H__ | ||
+ | #define __SAMPLE.H__ | ||
+ | |||
+ | #if _MSC_VER > 1000 | ||
+ | #pragma once | ||
+ | #endif | ||
+ | ヘッダファイルプロトタイプ宣言 | ||
+ | |||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | |||
+ | のように記述すると良いと思います。インクルードガードによる手法をサポートしつつも、#pragma onceの機能も有効利用できます。コンパイル速度が#pragma onceの方が早いので、おすすめです。他のコンパイラでも速度が速くなるようにインクルードガードを実現するには、冗長インクルードガードと呼ばれる手法を使います | ||
+ | |||
+ | <syntaxhighlight lang="cpp"> | ||
+ | #ifndef __SAMPLE.H__ | ||
+ | #include "sample.h" | ||
+ | #endif | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | のようにしてインクルードガード下上でさらにインクルード分のところでも読み込むかどうかを判断する処理を加えます。インクルード部がかなり煩雑になりますが、2重に読み込むことをより早い段階で避けることが出来るので、コンパイル速度の向上が見込めます。 | ||
+ | |||
+ | |||
+ | [[C PlusPlus#Cにもあった技術|C++]]へ戻る |