「C言語/前処理指令」の版間の差分

削除された内容 追加された内容
編集の要約なし
Ef3 (トーク | 投稿記録)
s/source/syntaxhighlight/38, cleanup
タグ: 2017年版ソースエディター
16 行
 
条件付き取り込みの記述は次のようになっている。
<sourcesyntaxhighlight lang=c>
#if 定数式1
グループ1
24 行
グループ3
#endif
</syntaxhighlight>
</source>
 
 #if,#elif,#elseは、それぞれ制御文のif,else if,elseと同様の使い方をする。
32 行
 
定数式では次の形式の単項演算子式を含んでもよい。
<sourcesyntaxhighlight lang=c>
defined 識別子
defined (識別子)
</syntaxhighlight>
</source>
defined単項演算子は、
識別子がその時点でマクロ名として定義している場合1と評価し、
41 行
 
また、次の形式の前処理指令もある。
<sourcesyntaxhighlight lang=c>
#ifdef 識別子
グループ
#endif
</syntaxhighlight>
</source>
これは次の前処理指令と等価である。
<sourcesyntaxhighlight lang=c>
#if defined 識別子
グループ
#endif
</syntaxhighlight>
</source>
 
<sourcesyntaxhighlight lang=c>
#ifndef 識別子
グループ
#endif
</syntaxhighlight>
</source>
これは次の前処理指令と等価である。
<sourcesyntaxhighlight lang=c>
#if !defined 識別子
グループ
#endif
</syntaxhighlight>
</source>
 
<ref>『JISX3010:2003』p.112「6.10.1 条件付き取り込み」</ref>
71 行
インクルードガードの記述は次のようになっている。
 
<sourcesyntaxhighlight lang=c>
#ifndef インクルードガード用の識別子
#define インクルードガード用の識別子
78 行
*/
#endif
</syntaxhighlight>
</source>
このヘッダファイルをインクルードする際、
2回目以降は「インクルードガード用の識別子」が定義されているため、
84 行
 
また、コンパイラによっては次のようなインクルードガードの記述もある。
<sourcesyntaxhighlight lang=c>
#pragma once
</syntaxhighlight>
</source>
{{See also|[[w:en:pragma once]]}}
 
== ソースファイル取り込み ==
92 ⟶ 93行目:
 
ソースファイル取り込みの記述は次のようになっている。
<sourcesyntaxhighlight lang=c>
#include <h文字列>
又は
#include "q文字列"
</syntaxhighlight>
</source>
 #indlude前処理指令は、
h文字列ではヘッダを、q文字列ではソースファイルをそれぞれ取り込む。
「#include "q文字列"」の探索をサポートしていない場合や、探索が失敗した場合は、
同じ文字列を「#include <h文字列>」と読み替えたのと同じ規則で再処理する<ref>標準ヘッダーファイル(stdio.hなど)を、<syntaxhighlight lang=c inline>#include "ヘッダーファイル名"</syntaxhighlight>の形式で取り込む事は、重大なセキュリティホールとなり得るので、厳に慎むべきであ。</ref>
<ref>『JISX3010:2003』p.113「6.10.2 ソースファイル取り込み」</ref>
 
109 ⟶ 110行目:
*オブジェクト形式マクロ
次の形式の前処理指令をオブジェクト形式マクロと呼ぶ。
<sourcesyntaxhighlight lang=c>
#define 識別子 置換要素並び
</syntaxhighlight>
</source>
defineの直後に記述してある識別子をマクロ名という。
オブジェクト形式マクロは、
118 ⟶ 119行目:
*関数形式マクロ
次の形式の前処理指令を関数形式マクロと呼ぶ。
<sourcesyntaxhighlight lang=c>
#define 識別子(識別子並び) 置換要素並び
</syntaxhighlight>
</source>
識別子並びは省略可能で、仮引数を指定し、個々の仮引数は「,」で区切り、最後に省略記号「...」を指定してもよい。
関数形式マクロは、
177 ⟶ 178行目:
 
マクロ定義を無効にするには、次のように記述する。
<sourcesyntaxhighlight lang=c>
#undef 識別子
</syntaxhighlight>
</source>
識別子で無効にしたいマクロ名を指定する。
 
188 ⟶ 189行目:
行制御の記述は、次の2通りがある。
 
<sourcesyntaxhighlight lang=c>
#line 数字列
</syntaxhighlight>
</source>
この指令の次のソース行の行番号が、数字列で指定された行番号となる。
数字列は1以上{{formatnum:2147483647}}<ref>C99より前は、{{formatnum:32767}}</ref>以下の10進整数でなければならない。
 
<sourcesyntaxhighlight lang=c>
#line 数字列 "s文字列"
</syntaxhighlight>
</source>
この指令は、同様に行番号を設定し、s文字列でソースファイル名を置き換える。
 
また、次の形式の行制御の前処理指令もある。
<sourcesyntaxhighlight lang=c>
#line 前処理字句列
</syntaxhighlight>
</source>
この形式の前処理字句列は、
マクロ置き換えで、上の2通りの形式のいずれかと一致せねばならず、
211 ⟶ 212行目:
== エラー指令 ==
エラー指令とは、処理系に対し、
指定された前処理字句の列を含む診断メッセージを出力することを指示する前処理指令である。
エラー指令の記述は次のようになっている。
<sourcesyntaxhighlight lang=c>
#error 前処理字句列
</syntaxhighlight>
</source>
前処理字句列で出力する診断メッセージを指示する。
<ref>『JISX3010:2003』p.121「6.10.5 エラー指令」</ref>
223 ⟶ 224行目:
処理系が認識できないプラグマ指令は、無視する。
プラグマ指令の記述は次のようになっている。
<sourcesyntaxhighlight lang=c>
#pragma 前処理字句列
</syntaxhighlight>
</source>
<ref>『JISX3010:2003』p.121「6.10.6 プラグマ指令」</ref>
 
<code>#pragma</code> は標準の一部であるが、それに渡す''前処理字句列''は実装に依存する。
 
よって使い方については、詳しくはコンパイラのヘルプなどを参照せよ。
マイクロソフト Visual C++ が<code>#pragma </code> 指令をサポートしており、よく使うことがある。実は GCC でも<code>#pragma </code> 指令をサポートしている。<ref>Igor Zhirkov 著、古川邦夫 監訳『低レベルプログラミング』、翔泳社、2018年01月19日 初版 第1刷 発行、294ページ</ref>
 
使い方については、詳しくはコンパイラのヘルプなどを参照せよ。
 
== 空指令 ==
空指令とは、何の効果もない前処理指令である。
空指令の記述は次のようになっている。
<sourcesyntaxhighlight lang=c>
#
</syntaxhighlight>
</source>
<ref>『JISX3010:2003』p.121「6.10.7 空指令」</ref>
 
== あらかじめ事前定義された済みマクロ定数 ==
あらかじめ事前定義された済みマクロ定数がある。
そのマクロ名と意味は次のようになっている。
 
{|class="wikitable"
|+ 事前定義済みマクロ定数一覧<ref>[http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm N1653 Working draft changes for C99 preprocessor synchronization]</ref><ref>[http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#630 CWG Issue 630. Equality of narrow and wide character values in the basic character set]</ref>
!マクロ名!!意味
|-
256 行
|__STDC__||整数定数1.規格合致処理系であることを示す。
|-
|__STDC_HOSTED__||処理系が規格合致ホスト処理系の場合、整数定数1。そうでない場合(つまりフリースタンディング環境である場合)、(未定義ではなく)整数定数0。
|-
|__STDC_VERSION__||標準Cのバージョンを表す値(C95 では 199409L、C99 では 199901L、C11 では 201112L、C90 では定義されていない)。このマクロが定義されているか否か、および、定義されている場合の値は実装依存である。
|__STDC_VERSION__||整数定数199901L。
|-
|__TIME__||前処理翻訳単位の翻訳の時刻。("hh:mm:ss"の形式の単純文字列リテラル)
266 行
|__STDC_IEC_559_COMPLEX__||「IEC60559 互換複素数演算」の規定に合致することを示すための整数定数1。
|-
|__STDC_ISO_10646__||型wchar_tの値が、ISO/IEC 1064610646(UCS; Universal Coded Character Set)で定義された文字の符号化表現をもつことを示すためのyyyymmLの形式の整数定数。
|-
|__STDC_IEC_559__||IEC 60559浮動小数点仕様に準拠している場合に定義される。ISO/IEC 9899:1999(C99)以降で定義される。
|-
|__STDC_IEC_559_COMPLEX__||IEC 60559互換の複素数仕様に準拠している場合に定義される。ISO/IEC 9899:1999(C99)以降で定義される。
|-
|__TIMESTAMP__||ソースの保存日時。ISO/IEC 9899:1999(C99)以降で定義される。"Ddd Mmm dd hh:mm:ss yyyy" 形式
|-
|__func__||関数ローカルの char の static const 配列として、外側の関数の非修飾かつ非装飾の名前を返す。ISO/IEC 9899:1999(C99)以降で定義される。
|}
※ __DATE__と__TIME__はそれを使わなければ絶対に解決できない課題を解決するためにのみ使うべきであり、それ以外の場合に安易に使うべきではない。特に、バージョン値の代用としての使用は不適切である。
 
<ref>『JISX3010:2003』p.121「6.10.8 あらかじめ定義されたマクロ名」</ref>
 
275 ⟶ 282行目:
プラグマ演算子は、指定した文字列リテラルを文字列解除し、その結果をプラグマ指令の中の前処理字句列として実行する。
つまり、次の形式の指令は、その次の形式でも表現できる。
<sourcesyntaxhighlight lang=c>
#pragma listing on "..\listing.dir"
_Pragma("listing on \"..\\listing.dir\"")
</syntaxhighlight>
</source>
<ref>『JISX3010:2003』p.122「6.10.9 プラグマ演算子」</ref>