読者です 読者をやめる 読者になる 読者になる

【初心者C++er Advent Calendar 2016 13日目】予約済み識別子に注意しよう

C++

初心者C++er Advent Calendar 2016の13日目が空いてるようなの書きました。
本記事は初心者C++er Advent Calendar 201613日目の記事になります。
初心者C++er Advent Calendar 2016では 3回目の記事になりますが、今回は予約済み識別子の話です。

[予約済み識別子とは]

『予約済み識別子』とは『言語仕様』や『処理系』などで使用するために予約されている識別子のことです。
C++ では以下の3つのいずれかを満たす名前が『予約済み識別子』として予約されています。

  • グローバルスコープを持ち、_ で始まる名前
  • _ で始まり、その次が大文字の名前
  • __ を含む名前

例えば、__LINE__ みたいな定義済みマクロの名前であったり、処理系依存であれば msvc の _MSC_VER 定義済みマクロがそれにあたります。
要は『__ を含む名前とかはコンパイラやライブラリの実装で使う可能性があるからユーザは使わないでねー』というためのものですね。
ですので、以下のようなコードは未定義の動作になります。

// インクルードガードなどで名前の先頭に _ をつけてるのでダメ
#ifndef _INCLUDED_PATH_TO_
#define _INCLUDED_PATH_TO_

#endif

// _ から始まってる名前なのでダメ
typedef struct _X {
    // __ が含まれてる名前なのでダメ
    int value__;
} X;

インクルードガードのマクロ名に『_ から始まってる名前』を使ってるコードをよく見かけますが、これも厳密にいえば未定義の動作になります。

[まとめ]

実際のところ予約済み識別子を使ったところでそこまで問題になる可能性は低いと思います。
しかし、わざわざ未定義の動作になる可能性があるコードを書く必要もないので、C++ を書くときは注意するとよいと思います。 言語によっては _value みたいに『先頭に _ をつける事』を推奨してることもありますが、C++ では基本的に避けるべきです。
ですので、C++ では以下のように『名前の末尾に _ をつけること』が多いです。

// だめ
auto _value = 42;

// おっけー
auto value_ = 42;

こんな感じで基本的には名前の先頭に _ をつけるのを避けるように気をつければ問題ないと思います。
以上で、予約済み識別子の説明は終了です。
予約済み識別子警察には気をつけましょう。

[余談]

Vim を使ってる人は以下のプラグインをいれてみるといいと思います。

[参照]