Cでゲームエンジンを書くのは合理的ですか?[閉まっている]


53

C ++が王様のように見えますが、私が言ったことから、Cはゲーム、特にコンソールでまだ広く使われています。しかし、Cでゲームエンジン全体を記述することは、今日では不合理でしょうか?CがC ++よりも優れている点はありますか?なぜ誰かがC ++を介してCを使用したいのでしょうか?


1
コンソールゲームはc ++ FYIを使用します!
アランウルフ

実際、Cは特定の規模、たとえば数万LOC程度までのゲームを書く方が簡単だと思います。これは、主にC ++に比べて複雑なデータ型を使用せずにビットとバイトに集中できるためです。しかし、一定の規模(たとえば数十万のLOCに達した後)で、実際に複雑なデータ型、より多くの型安全性、例外、テンプレート、さらにはCおよびC ++コードと組み合わせるためのC ++以外のもののスケール(たとえば数百万)。

Cには、ABIでも広く移植できるという追加の利点もあるため、既存のCコードを取得して、FFIなどから他の言語で使用することが非常に簡単になります。C ++は、名前のマングリング、モジュールの境界を越えて安全に投げることができない、コンパイラ間でvtable担当者が同じではない、ベンダー間で標準ライブラリの実装が異なるなど、少し扱いに​​くいです。スタイルの外に出ますが、それでスケールの何かを書くのに時間がかかります。

回答:


49

しかし、Cでゲームエンジン全体を記述することは、今日では不合理でしょうか?

それは合理的ですが、質問はそれがあなたを何を買うのですか?Cが提供する極端な移植性を必要としない可能性が高く、哲学的に本当に設定されていない限り、C ++が提供するすべての機能を放棄するのは残念です。

CがC ++よりも優れている点はありますか?

コンパイル時間は改善されましたか?

なぜ誰かがC ++を介してCを使用したいのでしょうか?

それは主に美的な選択だと思います。多くの人がCが好きなのは、それがシンプルで最小限であり、すっきりしているからです。C ++には多くの優れた機能があります(名前空間だけで使用する価値があります)が、それは大きくて面倒です。


3
Id Tech 4まで
メガネ店

9
@ジョシュ:デバッグが簡単に!?Cプログラムは、主にポインターとメモリ管理のため、デバッグが難しいことで有名です。C ++プログラム(真のC ++プログラミングイディオムを使用する場合、可能な限りポインターとメモリ管理を回避する傾向がある)は、デバッグが数桁簡単です。
BlueRaja-ダニーPflughoeft

14
Cは単なる人間によって理解できます。C ++には多くの機能があり、経験豊富なプログラマーは、10年間毎日C ++を使用して生活しているにもかかわらず、そのことを学んでいます。
ヤリコンパ

13
C ++は大きな言語ですが、恐ろしい評判は主にホラーストーリーを読んだばかりで時間をかけて学習していない人々によって広まっています。学ぶべきことはたくさんありますが、その見返りに多くの価値があります。C ++を使用すると、Cではできない多くのことを表現できます。
11

2
@ BlueRaja-DannyPflughoeft #define malloc(x) my_malloc(x) #define free(x) my_free(x)とあなたは今メモリをデバッグしています。C ++では、あなたはメモリを割り当てるために非常に多くの方法(新しい、malloc関数、クラスのコンストラクタなど)があるのでとき、配分されるかを知ることはありません
YoYoYonnY

59

私は、いくつかの製品を出荷したpure-Cゲームエンジンと広範囲に協力してきました。CとC ++の両方のエンジンでの私の個人的な経験は次のとおりです。

  1. pure-C構造体を使用すると、構造体の配置に関する知識を活用でき、この情報を使用してオブジェクトの永続化層とシリアル化層を構築できます。私が使用したエンジンには、構造に関するこのメタデータを自動的に作成する簡単なヘッダーパーサーがあり、特定の種類のデータ操作を簡単にしました。任意のC ++ヘッダーファイルの解析は本質的に不可能であり、継承および仮想関数を追加するとすぐに、メモリ内の正確な場所を知ることができなくなります
  2. ヘッダーファイルを非常にコンパクトに保ち、構造体の前方宣言を利用できるため、コンパイル時間が大幅に短縮されます。
  3. テンプレートと継承を使用しなくても、特定のオブジェクトが何であり、何をしているのかを正確に把握するのは非常に簡単なので、デバッグを改善できます。

これらの利点はすべて、シリアル化されたオブジェクトでテンプレートと継承の使用を控える抑制されたc ++コードを使用して簡単に達成できますが、C ++のより混乱する要素がなければ単純さを強制する方が簡単だというCTOの決定でした利用できます。

個人的には、forループで変数を正しく宣言する機能と継承の完全に正当な多くの使用法を本当に見逃したため、これは少し極端だったと思います。しかし、最終的にはすべてのことを考慮して、生産性を犠牲にすることはありませんでした


5
Cでの継承の実装を妨げるものは何もありません。C99を使用する場合、forループで変数を宣言できます。
jsimmons

15
ポイント3には同意しません。Cで乱雑でデバッグしにくいコードを書くのは、C ++の場合と同じくらい簡単です。デバッグの改善は、C言語に固有のものではありません。
ダン・オルソン

7
クリーンなコードであっても、C ++では理解しにくい場合があります-オーバーロード、テンプレート、仮想関数、および例外により、実際の制御フローが何であるかを一目で正確に確認することははるかに困難です。
キロタン

6
@Dan:単に多くのものを用意するだけで、C ++のデバッグが難しくなります。それはC.なりますので-あなたはもちろん、それはCのようにデバッグするように簡単になる場合には、その原料のいずれかを使用してから自分を制限することができます

実際、Cが好きな理由は少ないです。たとえば、CI memcpyでは、型システムがctorやdtorのコピーを許可していないため、何でもビットとバイトをコピーできます。明示的に戻るまで明示的に関数を終了することはできないため、ほとんどのコード行で副作用をロールバックする必要がないことを知ってコードを書くことができます。スローされる例外はありません。そんなに簡単にデータ構造を書き込み、この作るのすべて- C ++でちょうど標準準拠を書くことはvector非常に時間がかかり、あなたがそれをしたい場合は特に...

18

C ++とLuaで書かれた2DゲームエンジンをCとLuaに書き換えています。これまでの経験は非常に良好です。明らかに、ベクトル演算と行列演算を行うことはCで見栄えがよくありません。しかし、それとは別に、C ++開発者として10年以上費やした後の経験は非常に新鮮であることがわかりました。

Cには、C ++よりも多くの利点があります。

  1. コンパイラは、静的初期化時にコードが実行されないようにします。これにより、キーとして使用される文字列などのグローバルデータを静的に割り当てることが完全に安全になります。
  2. 透明性。Cでは、変数の割り当てまたは割り当てまたは定義によって、コードのロードが実行されることはありません。C ++はコピーコンストラクターを自動的に生成するため、割り当てを実行するときに実行されるものを制御できなくなります。
  3. 関数名がマングルされていないため、多くのデバッグ簡単になります。
  4. 通常、Cでmemcpyを使用しても問題ありませんが、コピーコンストラクターが実行されないため、C ++で問題が発生しやすくなります。ことを考えるとmemcpyのは、はるかに高速よりもあるのstd ::コピーが問題ということ。

それとは別に、Cの考え方に入るには多くの利点があります。C ++では、物事を少し一般化しすぎて抽象的にすることがよくあります。CIでは通常、get-setメソッドなどを削除し、多くの場合、動的配列を使用するのではなく、固定サイズの配列を事前に割り当てます。多くの場合、Cでより短く、より簡単にデバッグできるコードになります。通常、データ構造はよりフラットで、デバッガーで簡単に表示できます。

公平を期すために、Cだけでアプリを作成することは決してありません。それが機能する理由は、Cを非常にうまく補完できるLuaのような高レベル言語と組み合わせるためです。

IdソフトウェアはCIでのエンジンのほとんどを書いていると信じています。Cで書かれたヴォルフェンシュタイン城への帰還を見ることができます。

私は上の私の経験のいくつかについて書いたC対Cのスケーラビリティ++STLのベクトルの欠点は、単なる配列と比較します。


11
参考までに、確認したすべてのインスタンス(つまり、darwin gccとvc2008)で、std :: copyは、両方のタイプがPODである場合、memcpyの呼び出しにコンパイルされます。
ブラッフル

3
また、RE:STLベクトルと単純な配列、ベクターのいい部分を使用して、イテレーターが気に入らなければイテレーターの代わりに通常のCポインターを使用してみませんか?&myvector [N]を実行するだけです。Cコードが同じ方法でメモリ割り当てを行うと仮定すると、両方の長所のようです。または、forループでBOOST_FOREACHをチェックしてください。Cよりもさらにシンプルにします
。– BRaffle

1
std :: copy memcpyについてのヒントをありがとう。知りませんでした。アレクサンドレスクが数年前にこれを扱ったとき、そうではなかった。C ++イテレータについて。それは主に哲学についてであり、私はC ++が私が働く人々のために、C ++の機能を利用するためにプログラムされることを意図した方法をプログラムしようとしています。主に、STLコンテナーのようなC ++の改善が古いCの方法で行うよりも常に良いとは限らないことを指摘するために作成されました。
エリックEngheim

7

他の誰かが指摘したように、C ++はあなたが立つことができる大きな肩(BOOST、STLなど)の利点をもたらします。最終的には個人的な選択ですが、利用可能なリソースがあるため、C ++を選択します。C ++に使用したくない機能がある場合は、使用しないでください。


1
商用および社内のゲームエンジンの99%は、さまざまな理由(パフォーマンスの保証、デバッグ可能性、スレッドの安全性、制御)のためにBoostおよびSTLから離れています。
カイ

42
そして、統計の99%が構成されています。
ブラッフル

すべての統計を引用するのは、やや規則にすべきだと思います。
マットジェンセン

3

最近、だれもがCを独占的に使用しているとは思いません。通常、Cはより高いレベルの言語と混ざり合っています。

Cでのプログラミングには、たとえばC ++でのプログラミングに比べていくつかの利点があります。C ++ 、ユーザーには見えない多くのことを内部で実行できます。注意しないと、パフォーマンスが低下する可能性があります。キャッシュの使用に関しては、C ++ ひどくなり、パフォーマンスが低下する可能性があります。

したがって、ゲームのパフォーマンスに重要な部分を、従来のC ++の方法ではなく、Cのような方法で記述することには、いくつかの利点があります。しかし、最近、Cでゲーム全体を実際に書いている人を聞いたことはありません。

iPhoneなどの一部のプラットフォームでは、C ++を使用すると、特定のキロバイト単位で実行可能ファイルのサイズを増やすことができます(どれだけ忘れたのか、すみません)。これが、一部のiPhone開発者がCとObjectiveを組み合わせてコードを記述する理由です-C。


3

今日、C ++の代わりにCでゲームエンジンを作成するのが不合理である理由を、STLとBOOSTで説明します。

私はそれが執筆さらに別の価値があるだろうか想像することはできませんlistあなたが箱から出して動作するコードに頼ることができたときに実装(とあなたが書く必要はありませんので!)


1
大きなスタジオでは実際にブーストを使用していますか?移植性のため、STLの使用についても議論が続いています。少なくともコンソールエンジンの場合。
スライスした

2
個人的には、c ++ / luaインタラクションにBoost.FunctionTypes(gamedev.net/reference/programming/features/CPPLuaExport/…を参照)と、均一な乱数生成(粒子システム用)にBoost乱数ライブラリを使用しています。また、Boost.Foreachはすてきです。ところで、大きなスタジオがBOOSTを使用していない場合、誰が気にしますか?彼らには、独自のSTLライブラリをゼロから作成する人材がいます。
ロリス

1
ええ、Cにも同様のライブラリがあることを認識しています。
jsimmons

2
多くの人がゲームでブーストを使用していると思います。しかし、それは私たちの多くにとって要件からは程遠い(または望ましい)ものです。
ダン・オルソン

6
人々は、あなたが信じていることは無関係です:あなたはどちらか知っているかは知りません
o0 '。

3

Cでゲームエンジンを作成するのは合理的です。高速で、複数のシステムに移植できます。たとえば、Androidで使用できます(NDKを使用)。iPhoneで使用できます(Objective cはcの単なる拡張です)。また、Linux、Mac、WindowsなどのメインOS用に使用することもできます。cに慣れている場合は、試してみることをお勧めします!


2

もちろん合理的です。私は個人的にそれをしないだろうし、私が知っているほとんどのCファンは実際には.cppファイルにCのようなコードを書くだけだ。しかし、言語はそれが本当に重要でない場所に十分に似ています。

誰かがこれを行うことを選択する理由については、主に反C ++の哲学によるものだと思います。個人的には、これが「CスタイルC ++」よりもCを選択する良い理由だとはまだ思いません。typedef struct crazinessは、Cを回避するのに十分な理由であり、他にも多数あります。

残念なことに、CとC ++はどちらもかなりひどい言語です。これが、近年人々がスクリプトで多くのコードを実行しようとしている理由の1つです。

Cで働いている人々の例を探しているなら、idを無視できます。私は彼らがずっと前にCを放棄したことを読んだことを思い出します。ただし、Cryptic Studios(Star Trek Online)はすべてのエンジン開発をCで行います。私の知る限り、そうです、それは具体的な利点よりも哲学のせいです。


0

はいといいえ。はい、私は数年前にそれをやりましたが、私のゲームは、ダム端末上のプレーヤーで、Unix(Linuxではない)64ビットリモートサーバーで3Dで実行する必要がありました。些細なことではありませんでした。CはLUAを統合したいのですが、最終的にはluaをC ++で動作させるようになったので、それは可能ですが、実行しないでください。


0

可能な良い答えは「両方を使用する」かもしれませんか?

panda3dプロジェクトは最適化され、cythonを使用するかそれらの部分を再コーディングすることでボトルネックを解消できると聞きました。

ほとんどの場合、最適化が必要な部分は多くの反復とネスト、または多くの数値計算を伴う部分であるため、私の(野生の)推測は、Cを使用して両方の言語を使用することです低レベルのプログラミングが多く含まれるパーツの場合、スピードが必要なパーツにはC ++言語を、ゲームの残りの部分にはC ++を誤用することはできません。

理想的には、高レベルを念頭に置いてエンジンの高速部分を実行し、ネスト/ループをはるかに少なく使用するスクリプト言語またはC ++を使用します。

もちろん、エンジンを特別な種類のゲーム専用にする場合を除き、開発者が行う必要があるすべてのゲームに適合するエンジンを作成することはできません...

しかし、私は経験豊富なゲーム開発者でも経験豊富な開発者でもないので、アドバイスを当然受けないでください。Cは、ゲームと同じくらい大きなプロジェクトのために、高速で良いC ++コードを書くことを強制していると思います別のものです...



0

Cコードは通常、有効なC ++コードです。

C ++の主な問題はそれを間違って使用していることです(Linus Torvaldsはこの理由それを嫌っています、彼はライブラリの移植性などの他の問題も持っていたので、彼はオペレーティングシステムレベルで働いており、あらゆるランダムで物事を実行する必要がありますそこにチップ)。

たとえば、c ++ std :: vector <>(または同様のコンテナ)に対してcstyle array []を使用する利点はほとんどありません。

ベクトルはタイプセーフであり、境界チェックできます(get()または[]のいずれかを使用して要素にアクセスできます。配列チェックメソッドを使用しない場合でも、ポインターでサイズを移動するのではなく、サイズを照会できます)。

ただし、たとえば、コンストラクターでデフォルトサイズを宣言しない場合、ベクトル遅くなる可能性があります。また、ベクターに物事を追加すると、サイズを変更する必要がある場合に速度が低下する可能性があります。C ++ 11には、均一な初期化(同じ構文を使用してベクトルを宣言および初期化できる)などの多くの利点も追加され、コピーを回避できる移動コンストラクターがあります。独自のカスタム初期化子を作成することもできます(何らかの理由でmallocを使用する以外のことをしたい場合)。

またはもちろん、サイズを変更する必要がある場合、ベクターを使用する方が簡単です。mallocをいじったり、手動でコピーしたりする必要はありません。

C ++はオブジェクト指向のコードを提供します。コンパイルすると、実際にコードを操作する人間の抽象化に過ぎないため、同じくらい効率的になります。コンストラクターのようなものはオブジェクトの作成を遅くすることができますが。ただし、デフォルト値を設定するにはコンストラクターが必要です。そうでない場合は、コンストラクターを使用せずに(()を省略することで)オブジェクトを初期化できます。

しかし、オブジェクト指向により、ゲームのプログラミングがはるかに簡単になります。ゲームはしばしばオブジェクトを扱います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.