予約語

とは、プログラミング言語などの人工言語の仕様に定められているもので、ユーザープログラムの開発者が自分で付ける識別名としては利用できない特定の文字列のこと。たとえば変数名や関数名などに使用することができない、とあらかじめ定められた文字列（単語、字句など）のこと。あるいは、プログラミング言語などにおいて、固定された意味を持っており、その結果、プログラマーの側ではその意味を再定義できない語。
概要.
予約語と似ていてしばしば混同されてしまう言葉に「キーワード」() があるが、プログラミング言語の種類、また文脈によってreserved wordとkeywordは全く違う意味を持ちうるので、両者は異なる用語・概念と扱われている場合が多い。そのため、一旦は別物である可能性が高いとみなして扱うほうが安全である。
。この場合予約語はキーワードとは別のものである。
一方、「キーワード」は言語仕様上特別な意味を持った語のことである。キーワードであっても予約語でないこともあるし、その逆もある。たとえばECMAScript (ECMA-262) 5th Edition (ES5) では、codice_1やcodice_2は予約されており予約語だが言語で使われておらずキーワードではない。しかしECMA-262 6th Edition (ES6) では新たにサポートしたクラス構文のために使われるキーワードとなった。ECMA-262 では、キーワードは予約語の部分集合で、言語で制御構造などの意味を持つ予約語がキーワードである。Javaでは言語で使われていないcodice_3やcodice_4もキーワードである。SQLには予約されたキーワードと予約されていないキーワードがある。例にも出てきたように、個々の規格によっても両者それぞれ微妙に意味が違うこともある。
なお、FORTRANやPL/Iのように予約語を持たないプログラミング言語もある。
「予約されたキーワード」() や「予約されていないキーワード」() という用語が使用されている場合もある。
共通言語基盤 (CLI) 向けの共通言語仕様 (CLS) にしたがって実装されたC#やVB.NETでは、キーワードを識別子として利用する構文が用意されている。
上記の機能は、CLSを満たす他の.NET言語で記述されてアセンブリに公開されたシンボルの名前を使う場合などでも有用である。例えばC#ではcodice_11はキーワードではないため、プロパティなどの名前として使用できるが、VB.NETではキーワードであるためそのままでは使えず、相互運用に支障が出る。そこで、シンボル名を使用する際にcodice_12と記述することでVB.NETでも識別子として使えるようになる。
主な言語の予約語やキーワード.
C言語.
C言語はキーワード (keywords) の他、予約済みの識別子 (reserved identifiers) を持つ。正確な詳細は ISO/IEC 9899 規格を参照のこと。
なお、IBMのz/OSのドキュメントでは「reserved keywords」と呼んでいるが、この用語はCの標準規格に準じたものではなく、厳密には誤りである。
C++.
C++には、C言語由来のキーワードと、C++で新たに追加されたキーワードがある。また、予約済みの識別子のルールもCと似ているが、若干異なる部分がある。正確な詳細は ISO/IEC 14882 規格を参照のこと。
C#.
C#の構文はC/C++やJavaによく似ており、キーワードも類似している。
COBOL.
COBOLは、500ほどの予約語がある。
FORTRAN.
FORTRANにはキーワードがあるが、予約語を持たない。そのため、ユーザー定義の名前（識別子）にcodice_13やcodice_3のようなキーワードと同じ綴りを使うこともできるが、プログラムの可読性やメンテナンス性を著しく下げるため使うべきではない。
隣接するキーワードは、その間に1つ以上の空白文字を入れる必要があるものもあれば、必要がないものもある。例えばcodice_15をcodice_16と書くことはできるが、codice_17をcodice_18と書くことはできない。
Java.
Javaの構文はC/C++によく似ており、キーワードも類似している。
Pascal.
Pascalでは特殊記号 () の中に含まれる部分集合として、綴り記号 () という用語が使われる。『PASCAL 原書第4版』（培風館、1981）では word symbol の訳として「綴り記号」という用語を使っている。また、同書には「綴り記号（すなわち予約語）」という記述がある（p.12）。
ISO/IEC 7185:1990 の翻訳である JIS X 3008:1994「プログラム言語Pascal」では、「」に対して「予約語」という翻訳を割り当てている。
特殊記号は、codice_19, codice_20などの演算子に使われる記号に加えて、codice_21, codice_22などの綴り記号を含む。
典型的な予約語・キーワード.
なお、C系の言語では、BASIC系の言語におけるcodice_39に直接相当するキーワードおよび構文は存在しない。C系言語のcodice_40は複合キーワードや専用構文などではなく、codice_41節に続く別のネストされたcodice_13文とみなされる。処理系によっては、あらかじめ定められたネスト数の上限に達するとコンパイルエラーとなる。
キーワード指向の言語と記号指向の言語.
抽象構文的には全く違いは無いにもかかわらず、具象構文・字句構文（lexical syntax）的な違いは見た目の違いとしてわかりやすいこともあり、しばしばプログラマの好みの問題になりやすい。代表的にはブロックが codice_43 か codice_44 か、などといった点であるが、そういった要素に記号を多用しがちな言語と、キーワードを多用しがちな言語がある。記号を使うのは簡潔だが、やりすぎると一見では暗号のようになりかねない（PerlやAPLなど）。キーワードを使う言語は冗長だが明示的という点は利点だが、識別子に使える名前が制限され、フォントを変えるなどシンタックスハイライトの支援がないと見た目にも区別しづらい。キーワードは全て大文字とし、識別子には必ず大文字アルファベット以外の文字が含まれるようにする、といった解決法もある。はISO 646の国際版に、世界的に7ビットの文字コードは定着したが、以前は、あるいは今もEBCDICは絶滅していないので記号は自由に使えない場合もあった。
コンテキストキーワード.
コンテキストキーワード (contextual keywords) はC#やC++などの言語で採用されている特殊なキーワードで、文脈キーワード、文脈依存キーワード (context-sensitive keywords) とも言われる。
言語を後から拡張する場合、新しい構文やキーワードあるいは予約語を追加すると既存のコードとの互換性が壊れてしまう場合がある。例えば、既存の変数やメソッドの名前が新しいキーワードあるいは予約語と同じだった場合、新しい言語仕様では構文エラーとなる。しかし、完全に将来の拡張を予期してあらゆるキーワードを予約しておくことは困難であり、予約語が拡張の障害になりうる。
そこで、新しく拡張された構文の中でのみキーワードとして動作するのがコンテキストキーワードである。コンテキストキーワードは特定の構文以外では変数などの名前として使用できるため、既存のコードを破壊することがない。
例えば、C#のプロパティ構文では、C# 1.0の登場当初からcodice_45、codice_46、codice_47という多くの名前に使われているであろう語をコンテキストキーワードとして定義している。これは例えばC/C++やJavaのコードをC#に移植する際に、名前の衝突を避けるのに役立つ。C# 5.0で追加されたasync/await構文でも、コンテキストキーワードを利用して言語仕様が拡張されている。
Cでは、例えばcodice_48やcodice_49などはプリプロセッサディレクティブの文脈では命令のひとつとして認識されるが、それ以外では通常のユーザー定義識別子として使用することもできる。
C++では、例えばC++11で追加されたcodice_50やcodice_51は単独ではキーワードではなく、通常は変数名や関数名などの識別子として使用することもできるが、文脈によっては特殊な意味を持つようになる。
マイクロソフトによる独自の言語拡張であるC++/CLIおよびでは、プロパティやデリゲートなど、標準C++からの拡張機能に関連するキーワードはすべてコンテキストキーワードとして規定されている。
コンテキストキーワードの問題点.
public class MyClass {
 private string value; // value は setter でのみ使われるコンテキストキーワードなので、ここでは衝突しない。
 public string Value {
 get { return value; } // value は setter でのみ使われるコンテキストキーワードなので、ここでは衝突しない。
 set { value = value; } // フィールド MyClass.value への代入ではなく、パラメータ value への自己代入となる。
 //set { this.value = value; } // フィールドへの代入とするには、this による修飾が必要。
var obj = new MyClass();
obj.Value = "hoge";
System.Console.WriteLine("Value = \"{0}\"", obj.Value);