msvcでテンプレートを大量に使うなど非常に重たいコードをコンパイルしていると、
fatal error C1060: ヒープの領域を使い果たしました。
というエラーが出ることがある。
Visual Studioのデフォルトのコンパイラは未だに32bitである。出力するバイナリが32bit用か64bit用かに関わらず、コンパイラそれ自体は32bitなのだ。とはいえ、ほとんどの場合32bitコンパイラで特に問題ない。
ただ上述のC1060のエラーが出る場合、この32bitが足枷になっている場合がある。メモリを2GBまでしか使えないので、巨大なコードのコンパイルにはメモリが足りない場合があるのだ。こんなとき、64bit用のコンパイラツールセットを使うことで解消される可能性がある。
設定方法
ネット上で調べてみると色々な方法が散らかっていてどの設定方法が適切なのかよく分からないが、とりあえず以下の方法が簡単だった。
64bitコンパイラツールセットを使いたいプロジェクトに対して、.vcxprojファイルを直接書き換える。
.vcxprojファイルを開くと、次のようなブロックがある。
<PropertyGroup Label="Globals"> ... </PropertyGroup>
この中に次のように一行書き加えればよい。
<PropertyGroup Label="Globals"> ... <PreferredToolArchitecture>x64</PreferredToolArchitecture> </PropertyGroup>
<PropertyGroup Label="Globals">
はプロジェクトのプロパティにおける"すべての構成"に相当する設定だと思われる。Release、Debugなどの構成やプラットフォームごとに切り替えたい場合は、"Globals"ではなく各構成ごとのブロックに書き加えればいい。
根本的な対処
64bitコンパイラツールセットといえどもPCに搭載されているメモリ容量という限界はあるため、コードそのものがあまりに汚い場合は無駄である。
コンパイラは基本的に.cppなどのファイルを1つずつコンパイルする。この一つの.cppファイルの中で大量のクラステンプレート、関数テンプレートのインスタンス化が発生することが、上記のC1060エラーのよくある原因である。何でもかんでもヘッダーに書いてその全てを一つの.cppファイル中にincludeしたりすると、しばしばこのような事態になる。
クラステンプレート、関数テンプレートのインスタンス化を小さな.cppファイルに分割するという手は有効だ。明示的インスタンス化を活用したり、テンプレートでない関数の中に押し込んだりして分割コンパイルするよう工夫すれば、上のエラーは回避できる。……かもしれない。