2016年12月21日 (水)#includeの取扱はご注意
おはようございます。
昨日まで、風邪でダウンしていたプログラマS.T.です。
今回は久々にプログラマ的記事です。
UnrealEngine4(以下UE4)を使っていると、陥る罠についてお話したいと思います。
UE4にはUnityビルドシステムという機能があります。
この機能を使用する事でコンパイルが高速に行えます。
具体的にどの様な事をこのシステムで行っているか簡単にいうと、
いくつかのcppを合体させ、一括にコンパイルする事でバラだったcppのリンク時間が大幅に削減されます。
例えば「TestGame」というプロジェクトを立ち上げ。
「Hoge00.cpp」「Hoge01.cpp」「Hoge02.cpp」というcppファイルを作成します。
すると、Unityビルドシステムにより「Modul.TestGame.cpp[From A]」というファイルが作成されます。
※後述の為に[From A]と名付けます。
この中身は下記のような記述になっています。
Modul.TestGame.cpp[From A]=====
#include "Hoge00.cpp"
#include "Hoge01.cpp"
#include "Hoge02.cpp"
EoF============================
初めて、このコードを見た時、
「あー、なるほどなこれは確かに早くなるな、でも怖くてあまり使いたくないな。」
というのが正直な感想です。
僕がこの時感じた恐怖は、勝手に自分の知らないところで#includeが使われている所です。
C++を触ったことある人なら誰でも経験するであろう、多重インクルードの恐怖!!
これに陥ると、ほんと時間と気力を奪われます。
なので、僕は#includeに関しては、特に慎重に取り扱う事を心がけています。
これから、このシステムにおける、個人的に一番恐ろしい所についてお話します。
「正しくインクルードできていなく、本来はコンパイルエラーが発生する所で、エラーにならない事がある。」という事です。
「ならない事がある」という書き方をしていますが、大規模で長期のプロジェクトに携わっていると、
100%どこかのタイミングで発生していまう、問題です。
具体的にどのような事かというと。
上記のファイルの中身が以下のようだった場合です。
Hoge00.cpp=====================
#include "TestGame.h"
#include "Hoge00.h"
[省略]
EoF============================
Hoge01.cpp=====================
#include "TestGame.h"
#include "Hoge01.h"
#include "Hoge02.h"
[省略]
EoF============================
Hoge02.cpp=====================
#include "TestGame.h"
void Hoge02::Hoge()
{
[省略]
}
EoF============================
本来ならば、Hoge02::Hogeの定義が見つからないと、エラーになるはずです。
しかし、この場合は「Hoge01.cpp」に記述されている、「#include "Hoge02.h"」があることによって、ビルドが通ってしまいます。
そして、このUnityビルドシステムは個人の開発環境毎に異なる物が作成されます。
AのPCとBのPCでは「Modul.TestGame.cpp」の中身が異なるのです。
BのPCの「Modul.TestGame.cpp[From B]」は以下の記述だとします。
Modul.TestGame.cpp[From B]=====
#include "Hoge00.cpp"
#include "Hoge02.cpp"
#include "Hoge01.cpp"
EoF============================
「Hoge01.cpp」「Hoge02.cpp」のインクルードの順番が入れ替わっています。
この場合、「Hoge02.cpp」ビルドは通りません。
仮にビルドが通り、動作の保証されている状態でSVNへコミットしたとしても、他の人の環境ではビルドエラーが発生する可能性が生まれます。
このシステムについて理解せずにコミットが行われ、自分の環境でエラーが発生すると、非常に迷惑です。
なので、#includeは記入者がしっかり管理してください。
テスト実装時に一時的に必要だったが、現在はもう必要がない#includeは削除してください。
しかし人間です、どこかで間違う事はあります。
なので、#includeが正しく行われているかどうか確認する方法があります。
それは「UnityビルドシステムをOFFにする」方法です。
UE4のSolutionExplorerに「TestGame.Build.cs」というファイルがあるはずです。
そこに1行書き足します。
TestGame.Build.cs==============
public TestGame(TargetInfo Target) {
[中略]
BuildConfiguration.bUseUnityBuild = false;
}
[中略]
EoF============================
以上です。
これにより、ビルドの時間はかかってしまいますが、正しく#includeされていない場合は確実にエラーを出してくれます。
毎回行うには時間がかかりすぎてしまう為、多用はできないですが、不安が残る場合や一度に多数のファイルをコミットを行う際は、
一度この状態でビルドする事をお勧めします。
後で、僕にグチグチ言われたくなかったら、、、笑
| 固定リンク | コメント (0) | トラックバック (0)
「プログラマー」カテゴリの記事
- 技術交流の業(2019.03.07)
- 福袋争奪戦デビュー(2019.01.31)
- 温泉旅行(2019.01.24)
- ゲーセンの近況(2018.11.29)
- 健康的にプログラミングを続けるためのちょっとした習慣(2018.10.18)
この記事へのコメントは終了しました。
コメント