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

C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

C++ の #include するファイル名について規格に基づいて実際に試してみた

C++の規格§2.9 Header names によれば、#include の や "fuga" におけるhogeやfugaの文字について、 hoge には > を除いて、 fuga には " を除いて、 ' \ /* // が含まれる場合は実装依存、またhogeのパターンの場合には " が含まれる場合にも実装依存と書いてある。

これについて実際試してみた。

btrfsファイルシステムでは NULL文字 と / 以外の全ての文字をファイル名に使用できるので、

% ls
"  '  *  \  test.cpp

こんな感じで " ' \ * というファイル名の被インクルードファイルを用意。それぞれの中身は、

% find . -type f -print -exec cat {} \;
./\
static_assert(0,"it's \\");

./"
static_assert(0,"it's \"");

./'
static_assert(0,"it's '");

./test.cpp
#include <">
#include "'"
#include "\"
#include "./*"
#include ".//*"

int main(){
  static_assert(0,"it's main");
}


./*
static_assert(0,"it's *");

こんな感じでincludeされればstatic_assertでコンパイルタイムに分かる様に小細工し、

% g++ --version | head -n 1 && uname -a
g++ (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773]
Linux LH-MAIN 3.4.11-2.16-desktop #1 SMP PREEMPT Wed Sep 26 17:05:00 UTC 2012 (259fc87) x86_64 x86_64 x86_64 GNU/Linux

こんな環境でコンパイルしてみた。

% g++ test.cpp -std=c++11
In file included from test.cpp:1:0:
./":1:1: error: static assertion failed: it's "
In file included from test.cpp:2:0:
':1:1: error: static assertion failed: it's '
In file included from test.cpp:3:0:
\:1:1: error: static assertion failed: it's \
In file included from test.cpp:5:0:
./*:1:1: error: static assertion failed: it's *
In file included from test.cpp:6:0:
.//*:1:1: error: static assertion failed: it's *
test.cpp: In function ‘int main()’:
test.cpp:9:3: error: static assertion failed: it's main

通った・w・;

…clangやMVC++ではどうなんだろうね?MSVC++についてはそもそもNTFSのファイル名に使える文字の制限も受けそうな気がするけど。
(Windowsとかよく知りませんしー・w・

おまけ

vim

f:id:USAGI-WRP:20121126192754p:plain