差分表示


#freeze
*&date(Y-n-j[lL],2013/5/26); c++03コンパイラの機能実装の比較

昔 ow や dmc のc++の(文法)実装状態をチェックしてる表をみたことあったなあ、と探してみれば、すぐみつかる.

http://cmeerw.org/prog/freecpp/

最終更新が2006で、それ以前のコンパイラの比較だけれど、チェックプログラムのソースが公開されていたので、ow 含むそれらよりも新しい(ヴァージョンの)コンパイラで試してみた。

もとより網羅されてるわけでないし今時のc++11世代のコンパイラの比較としては不十分だけど(SFINAEのチェックもなさげ)、owやdmcが以前よりよくなっているかを見る分には、と。

,,,dmc 8.56,ow 1.9,4.7.1 tdm,clang3.1 (+mingw462),vc8,vc9,vc11,bcc 5.5.1
,1,digraph,pass,fail[c],pass,pass,fail[c],fail[c],fail[c],fail[c]
,2,alternative tokens,pass,pass,pass,pass,fail[c],fail[c],fail[c],fail[c]
,3,new style casts,pass,pass,pass,fail[c] / 実質pass,pass,pass,pass,pass
,4,bool,pass,pass,pass,pass,pass,pass,pass,pass
,5,bool condition,pass,pass,pass,pass,pass,pass,pass,pass
,6,mutable,pass,pass,pass,pass,pass,pass,pass,pass
,7,explicit,pass,pass,pass,pass,pass,pass,pass,pass
,8,typename,pass,pass,pass,pass,pass,pass,pass,pass
,9,covariant return,pass,pass,pass,pass,pass,pass,pass,pass
,10,arrow operator return,pass,pass,pass,pass,pass,pass,pass,fail[c]
,11,overload enum,pass,pass,pass,pass,fail[c],fail[c],fail[c],pass
,12,nested class fwd decl,pass,pass,pass,pass,pass,pass,pass,pass
,13,friend namespace class,pass,pass,pass,pass,pass,pass,pass,pass
,14,class name injection,pass,pass,pass,pass,pass,pass,pass,fail[c]
,15,friend name injection,fail[e],pass,pass,pass,pass,pass,pass,fail[e]
,16,static const int,pass,pass,pass,pass,pass,pass,pass,pass
,17,delete const,pass,pass,pass,pass,pass,pass,pass,pass
,18,return void,pass,pass,pass,pass,pass,pass,pass,pass
,19,new scoping,pass,pass,pass,pass,pass,pass,pass,pass
,20,if stmt cond,pass,pass,pass,pass,pass,pass,pass,pass
,21,switch stmt cond,pass,pass,pass,pass,pass,pass,pass,pass
,22,while stmt cond,pass,pass,pass,pass,pass,pass,pass,fail[c]
,23,for stmt cond,pass,pass,pass,pass,fail[c],fail[c],fail[c],fail[c]
,24,defarg scope,fail[c],fail[c],pass,pass,pass,pass,pass,fail[c]
,25,namespace enum,pass,pass,pass,pass,pass,pass,pass,pass
,26,namespace template,pass,pass,pass,pass,pass,pass,pass,pass
,27,namespace template func,pass,pass,pass,pass,pass,pass,pass,pass
,28,using namespace template,pass,pass,pass,pass,pass,pass,pass,pass
,29,template non type,pass,pass,pass,pass,pass,pass,pass,pass
,30,explicit template instantiation,pass,pass,pass,pass,pass,pass,pass,pass
,31,template default all,pass,pass,pass,pass,pass,pass,pass,pass
,32,template default dependent arg,pass,pass,pass,pass,pass,pass,pass,pass
,33,template template arg,pass,fail[c],pass,pass,pass,pass,pass,pass
,34,template function explicit,pass,pass,pass,pass,pass,pass,pass,pass
,35,new template specialization,pass,pass,pass,pass,pass,pass,pass,pass
,36,partial template specialization,pass,pass,pass,pass,pass,pass,pass,pass
,37,partial ordering class templates,pass,pass,pass,pass,pass,pass,pass,pass
,38,member template class,pass,fail[c],pass,pass,pass,pass,pass,pass
,39,member template function,pass,fail[c],pass,pass,pass,pass,pass,pass
,40,bad alloc,fail[e],pass,pass,pass,pass,pass,pass,pass
,41,bad typeid,fail[e],pass,pass,pass,pass,pass,pass,pass
,42,throwing destructor,pass,pass,pass,pass (c++11fail[e]),pass,pass,pass,pass
,43,koenig lookup,pass,fail[c],pass,pass,pass,pass,pass,pass
,44,two phase lookup,pass,pass,pass,pass,fail[e],fail[e],fail[e],fail[e]
,45,empty base opt,pass,pass,pass,pass,pass,pass,pass,fail[e]
,46,return value opt,pass,pass,pass,pass,pass,pass,pass,fail[e]
,47,static assertions,pass,fail[c],pass,pass,fail[c],fail[c],pass,fail[c]
,48,right angle brackets,fail[e],pass,pass,pass,pass,pass,pass,fail[e]
,49,func predefined,pass,pass,pass,pass,fail[c],fail[c],fail[c],fail[c]
,50,hex float literal,pass,fail[c],pass,pass,fail[c],fail[c],fail[c],fail[c]
,51,long long,pass,pass,pass,pass,pass,pass,pass,fail[c]
,52,restrict,fail[c],fail[c],fail[c],fail[c],fail[c],fail[c],fail[c],fail[c]
,53,variable array,pass,fail[c],pass,pass,fail[c],fail[c],fail[c],fail[c]
,54,dynamic sizeof,pass,fail[c],pass,pass,fail[c],fail[c],fail[c],fail[c]
,55,empty macro argument,pass,pass,pass,pass,pass,pass,pass,pass
,56,enum trailing comma,pass,pass,pass,pass,pass,pass,pass,pass
,57,flexible array member,pass,pass,pass,pass,pass,pass,pass,pass
,58,compound literal,fail[c],fail[c],pass,pass,fail[c],fail[c],fail[c],fail[c]

~
補足
-いずれもwin用32bit版コンパイラ. win8でコンパイル&実行.
-fallにつけてる[c]はコンパイル出来なかった場合、[e]は実行結果で0以外を返した場合、を表してる.
-4.7.1tdm は mingw 4.7.1 tdm版.
-clang v3.1 はllvm公式のmingw用バイナリを、本家 mingw g++4.6.2 の環境に上書きしたもの。
-元表にあるow1.6やdmc8.4.5は試していない(インストールしてない)ので元表をみてください.
-vc8は元表にもあるけれど return void の結果が違ってる.
-47,48のみ必要ならば c++11 をコンパイルするオプションをつけている.(他はつけていない. 実はclangの不具合回避)

~
結果に fail があるチェックについて
-1 digraph: 交代記号( '{' が'<:'等) が使えるか.
-2 alternative tokens: and や and_eq のような記号の交代予約語が使えるか. ※ iso646.h(ciso646) で同様のものが#define定義されてる
-3 new style casts: const_cast<T>(t)のようなc++からのキャストが使えるか。clang が fail になっているのは本題とは別の virtual void A::f(); の実体が定義されていないことによるものでソースを実体定義に修正すれば問題なくパス。(このエラーは clangの挙動でも問題無いと思うけど、他のコンパイラがコンパイルできていることが興味深いかも)
-10 arrow operator return: メンバーのoperator->()の返型がT*,T,T&でない場合にコンパイルできるか. 
-11 overload enum: enum型を基本整数型とは別型として関数オーバーロードできるか?
-14 class name injection: クラス名インジェクションが機能してるか ※このソースだと B() : ns::A() {} でなく B::B() : A() {} になっているところ.
-15 friend name injection: friend名インジェクションが機能してるか ※class内friend 定義したものはクラス外(非friend)で定義されたものよりも名前検索の順位が低く、またそのことは引数のマッチよりも優先される...ってことかな。
-22 while stmt cond: while の条件式でローカル変数を定義できるか
-23 for stmt cond: for の条件式(2文目)でローカル変数を定義できるか
-24 defarg scope: デフォルト引数スコープの扱いに関するテスト. ow はメンバー関数のデフォルト引数は関数宣言側ならOKだが定義側だとNGのようで、また、関数内での外部関数宣言ではデフォルト引数が使えない模様。bcc5.5.1 はデフォルト引数の問題でなく static const 変数の扱いが定数でないためのfailで、static const int c=3;の代わりに struct B に先立ち enum {c=3}; を定義すれば ok.
-34 template template arg: template<template<class T> class T1> のような template template 引数を使えるか
-38 member template class: クラス・メンバーとしてclass テンプレートが使えるか. ※ow1.9 はクラス定義内では使えるが、クラス定義外でtemplateを2回使う記述はNG.
-39 member template function: クラス・メンバーとして関数 テンプレートが使えるか. ※ow1.9 はクラス定義内では使えるが、クラス定義外でtemplateを2回使う記述はNG.
-40 bad alloc: new が メモリー不足の時に bad alloc を投げるか. ※ dm 標準では行えてないが stlport のようにライブラリ実装で対処可能.
-41 bad typeid: Typeidの引数が不正だった場合 bad_typeid を投げるか. 
-42 throwing destructor: デストラクタ中に例外を投げることができるか. ※ clang++ 3.1 では通常は問題ないが -std=c++11 をつけでコンパイルすると実行時にハングした.
-43 koenig lookup: koenig lookup(ADL) が機能してるか. (関数呼出で、その引数の型が定義されている namespace から関数名をみつけられるか)
-44 two phase lookup:スコープ違いで同名のある関数の呼出が正しく行われるか
-45 empty base opt: 継承元class(struct)にメンバー変数が無い時0バイトにオプティマイズするか
-46 return value opt: クラス変数を返す時、コピーを発生させないようオプティマイズするか (VCはオプティマイズ指定しないとコピーになる)
-47 static assertions:[c++11]: static_assert があるか
-48 right angle brackets:[c++11]: templateで閉じカッコ2つを 空白を入れずくっつけて >> と記述して大丈夫か
-49 func predefined:[c99, c++11]: 関数名文字列 &color(0){_};_func_&color(0){_}; が使えるか
-50 hex float literal:[c99, c++11]: 16進数浮動小数点表記が使えるか
-51 long long:[c99, c++11]: long long を使えるか ※ bcc5.5.1は &color(0){_};_int64 ならある
-52 restrict:[c99]: restrict 指定が使えるか. ※ c++11には入らなかった機能.
-53 variable array:[c99]: 動的ローカル配列が使えるか. ※ c++14に入るかもらしい(?)
-54 dynamic sizeof:[c99]: 動的ローカル配列に対するsizeofが機能するか ※ c++14には入らない.(c++のsizeofはあくまでコンパイル時に決定できるモノのみ)
-55 empty macro argument:[c99]: 空のマクロ引数を許容するか ※ bcc はこのソースでは大丈夫だが、引数が1つの場合 NG
-58 compound literal:[c99, c++11]: (struct A){1, 2} のような構造体リテラル表記できるか.

bcc 5.5.1 を表に加えるんじゃなかった...面倒増えてしまった(いや本当はpassしてるのもひと通りみたほうがよいくらいだけど)~
vc が overload enum、two phase lookup あたりを修正しないのは、互換性がらみなんでせうかね? (既存の巨大ソースだと意図せず依存してそうな場合もありえそうだし).~