並ゲームプログラマの書き捨て場

ゲームプログラマやってる私の日記、雑記、備忘録、公開場所

Clang for Windows 3.6を入れた

徐々に進化している・・・徐々にだが・・・確実に!djannです。


過去にclang for windows 3.5を入れてみた - 並ゲームプログラマの書き捨て場
Clang for Windows 3.5のinstall.batの問題 - 並ゲームプログラマの書き捨て場でClang for Windows 3.5についての記事を書いた。見てみれば分かる通り、私は普段コンパイラはclang-cl.exeを使っている。

そして、ずいぶんと遅れたがLLVM Clangに3.6系統が登場しClang for Windowsも3.6がリリースされたので、もちろん入れてみた。


言い訳をすると仕事が忙しくて、素直に言うとものぐさな性格なので、これを書き始めたタイミングでは3.5から3.6で何が変わったかというのを私は知らない。ひとまず、単純な使用感の向上を求めてのバージョンアップだった。

さて、まずはインストールだが、こちらは前例たちと変わらない。インストーラを起動すれば旧バージョンの存在を検出、先に旧バージョンをアンインストールするかい?と聞いてくれる。もちろんYesと返答し、そのままインストーラを進めて行くだけだ。

そして3.5で問題だったinstall.batだが、中を見ると必ずループする形に変更されていた。これならば最新のVisual Studioが入っていない環境でも、ちゃんとx64向けのプロパティファイルが設置されてくれそうだ。


さて、実際にコードを書いてみた。プログラマおなじみのHello Worldである。

#include <iostream>


int main()
{
	std::cout << "Hello, Clang for Windows 3.6!!" << std::endl;
	
	std::cin.get();
}

今回は、無駄にVisual Studioに入っていない機能を使ったり等はしなかった。ちゃんと違うコンパイラが動くというのは3.5の時に確認済みだ。いやいっそ3.4の時に確認済みだ。


が、どうやら3.5の時と同様にtry catch throwでエラーが出てしまうらしい。内容もこれまた同様に、例外はまだコンパイル出来ないとのこと。
詳しく見ることが出来ていないので、もしかしたら3.5が使用されていますよ☆ということかもしれないが、ひとまずそんなところだ。3.5と同様に#define _HAS_EXCEPTIONS (0)を定義しておくことで、標準ライブラリを使用することが出来る。



うむ、このままでは何が変わったのかが全く分からない。表面的な部分しか舐めていないからだ。
この記事一旦下書きにしていたのだが、せっかくだから追加を書きながら、変更点を見てみることにした。自分に関わりそうなWindows Supportの部分だけではあるが。
参照元はこちら

・沢山のバグ修正が行われた
・x86x64環境でVisual C++を用いたセルフホストが可能になった?例外を除くMicrosoft C++ ABIに対応した。
・ATLやWRLヘッダを使えるようにVisual C++に合わせたハックを追加。
・Visual C++の__superキーワードを解釈できるように追加。
・Visual C++等での__vectorcall呼び出し規約が追加された。これはVisual Studio 2015のSTLで使われている。
・COFFファイルへデバグ情報を入れる為の基本サポートが行われる。
・筆者は英語が読めない。

つまりは、例外はいまだ使えない。今まで出来なかったブレークポイント*1とステップ実行が出来る・・・のか?これを書いている現在は試せる状況ではないので、後で各種実際にどういう挙動かを試してみたいと思う。もしかしたらブレークポイントはおけないかもしれない。いや置けない気しかしない。

試した場合は、以下に追記を書く予定だ。土曜日か日曜日、下手すれば更に先になってしまうだろうが。
※以下の追記にブレークポイントのテストを行った記録等は一切ない。別の部分の読み間違いから勘違いし続けている完全に無意味な文章なので注意。なおブレークポイントの情報は注記を行った。

追記その1

ATLやWRLの使用が可能なようにハック・・・辺りが簡素過ぎたので、明確にするためVisual Studioでしか通らないテンプレート周りのコードを試した*2。が、なんとClang for Windows 3.5でも以下のコードは通ってしまうようだ。警告付きだが(なお、テスト環境はVisual Studio 2010 Pro + Clang for Windows 3.5である)

template <class vType>
void print(){
	vType::type val = 0;
}

なお、Visual Studio 2010では一切の警告無しに通る。
他、インナーテンプレートクラスのクラススコープ内の特殊化等も、同様にVisual Studio 2010では一切の警告無く、Clang for Windows 3.5では警告を出しつつビルドが通った。どうやら結構な部分は、既に「VC++の独自拡張、汚い構文だ」と認識しつつコンパイル出来るようだ。過去のリリースノートの読破と、Visual Studioの独自構文への造詣を持つ必要があるようだ。

追記その2

commonly known template pattern (not to be confused with C++ templates). The template pattern is often implemented by having an abstract base interface class that all the subtype classes inherit from.
という文面を見つけた。テンプレート引数そのままではなく、基底クラスで実装されたサブタイプを派生クラスで使用できるということなのか?とすると、以下のような感じか?

template <class T>
struct base {
	using type = T;
};
template <class T>
struct derived : public base<T> {
	type val;	// ここが少なくともMSVCの拡張.
};

一応、ちゃんと以下のように警告が出てくれた。

warning : use of identifier 'type' found via unqualified lookup into dependent bases of class templates is a Microsoft extension [-Wmicrosoft]
          type val;

果たしてこれが3.6で追加されたものなのか、明日試してみなければならないだろう。これも3.5で実装済みであれば、また有用そうな情報を探すか、または英語をかっちりと学ぶ必要がある。

追記その3

追記その2で書いたことだが、3.5でも同様の結果になった。ではこれならばどうだ?と、3.5で通らずにVisual Studio 2010で通る以下のコードを書いてみた。

struct foo {
	typedef float type;
};
template <class vType>
struct base : public foo {
};
template <class vType>
struct derived : public sub<vType> {
	type val;
};

一段階経由することで、3.5で通らない形になり、それでもVisual Studi 2010では通る形だ。all the subtype classes inherit fromとはそれを指しているのではないか!と期待したのだが、どうやら3.6でも同様にビルドが通らない・・・。


ここでふと思った。原文に書いてあるknown template patternの部分だが、別段イタリックでもなんでもなく、いたって平凡なフォントである。英語圏では、何らかの用語などはイタリックにする等、見た目でそれが用語だと分かるようにする文化があると聞いた事がある。
つまり「known template pattern」という一定のパターンがあるわけではなく、あくまでただの説明として(この辺の良く知られてる、テンプレートに対するMSVC特有の名前検索パターンを取り入れたぜ。のような意味で)書かれていただけなのではないだろうか。それはいくら調べてもほとんど情報が出てこないわけだ。

一部の単語を見て早とちりした結果、この追記群は全く無意味な文章(私の無知さを辱めるという使い道はあるが)となってしまった。今後このような事がないようにする戒めとして、この記事はこのまま残しておくことにし、以降追記等は行わずに放置しよう。

*1:ブレークポイントは、今までもエディットコンティニュを考慮しないデバグ情報を埋め込むよう指定していれば置くことが出来、ステップ実行も可能だった。出来ないのは変数の内容を見る等である。なお、これは3.6でも同様なようだ。

*2:参照元の原文は「Added more MSVC compatibility hacks, such as allowing more lookup into dependent bases of class templates when there is a known template pattern. As a result, applications using Active Template Library (ATL) or Windows Runtime Library (WRL) headers should compile correctly.」である