« 自分を変えたい | トップページ | スケジュール管理は大事 »

2016年12月21日 (水)#includeの取扱はご注意

おはようございます。sun

昨日まで、風邪でダウンしていたプログラマS.T.です。bearing

今回は久々にプログラマ的記事です。

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されていない場合は確実にエラーを出してくれます。
毎回行うには時間がかかりすぎてしまう為、多用はできないですが、不安が残る場合や一度に多数のファイルをコミットを行う際は、
一度この状態でビルドする事をお勧めします。

後で、僕にグチグチ言われたくなかったら、、、笑wink

follow us in feedly
result = encodeURIComponent( "http://www.accessgames-blog.com/blog/2016/12/include-f573.html" );document.write( "result = " , result );&media=https%3A%2F%2Ffarm8.staticflickr.com%2F7027%2F6851755809_df5b2051c9_z.jpg&description=Next%20stop%3A%20Pinterest">

| | コメント (0) | トラックバック (0)

« 自分を変えたい | トップページ | スケジュール管理は大事 »

プログラマー」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/217647/64651091

この記事へのトラックバック一覧です: #includeの取扱はご注意:

« 自分を変えたい | トップページ | スケジュール管理は大事 »