hginit-ばかげた#ifdefs


8

ジョエル・スポルスキーの水銀の紹介を読んでいたとき、それは私を襲った:

「そして今、彼らがしていることは次のとおりです。各新機能は大きな#ifdefブロックにあります。そのため、1つのトランクで機能できますが、デバッグされるまで新しいコードが表示されることはありません。正直なところ、それはばかげています。」

なぜこれはとにかくばかげているのですか?これは、他に何もないにしても、単純に処理するのが簡単ではないですか?それは派手なことではありませんが、トリックを行います-少なくともあなたがすでにSubversionと「結婚」している場合。

欠点は何ですか?私は議論を理解していません。


スイッチが1つまたは2つしかない場合はばかげていませんが、ifdefsの入れ子にされた奇妙なグループの巨大なチェーンに対処する必要があり、理解しようとするのは忌まわしいことです。それもばかげています。複雑なブーストテンプレートコードは読みにくいと思いますか?
whatsisname

回答:


20

答えは次の文で与えられると思います:

安定したコードと開発コードを分離しておくことは、ソースコード管理でできることです。

#ifdefブロックを使用することにより、Cプリプロセッサでソース管理システムの機能をエミュレートします。それは仕事にとって間違ったツールです。

欠点は、おそらく多くのコードを複製することになる(関数定義全体を1回内側で、外側で一度#ifdef考える)か、またはコードが読めない(#ifdef関数内の単一行を含む-おそらく繰り返し)ことです。

最初のバリアントでは、バグを2回修正することになります(stableブランチからdevブランチにバグ修正をマージできる場合は必要ありません)。2番目のバリアントでは、stableブランチとdevブランチを分離するという本来の目的は実際には達成されませんでした。 。


2
+1:80年代、私はあなたが考えることができるほとんどすべてのUNIXシステム上で実行するデバッガを持っていました。バージョン4より前は、コードはに溢れていました#ifdefs。見ているだけで目が出血することを誓います。バージョン4の場合、別のファイルを使用してプラグ可能なアーキテクチャにアクセスし、RCSを使用し始めました(または、SCCSでしたか?)。生活が大幅に改善され、新機能の開発がはるかに簡単になりました。(しかし、少年が当時私たちがgitまたはhgを持っていたことを願っていますか?)
Peter Rowell

私は経験から#ifdefの地獄を知っています!バージョン管理の代わりとしては避けるべきだと私は同意します。
ジョルジオ

3

#ifdefsのネズミの巣であるコードを維持しているため(ただし、さまざまな理由があります)、そればかげています。特に複数の条件に対してテストする場合は、コードが読みにくくなり、保守がはるかに困難になります。


はい、私もこれをやりました、それはひどかったです。
2013年

1

既存のコードに手を加えることなく、すべての新しいコードを記述できることを前提としています。多くの場合、それを行う唯一の方法は、自分を何度も繰り返すことです。(たとえば、似ているがまったく同じではない方法の新しい方法)。

分散型VCSの主な利点の1つは、チームが独自の機能ブランチで作業し、他のユーザーと競合する作業を心配する必要がないことです。この戦略はその利点を打ち消します。

ツールを故意に誤用しているように見えるので、私にはばかげているように見えます。あなたがスイッチを作るつもりなら、それらを使う方法を学ぶ価値は確かにあります。


3
これはDVCSに限定されない
James

いいえ、そうではありません。戦略的に#ifdefsを配置した場合でも、既存のコードを変更することはできますが、古いバージョンはそのままにしておき#elseます。
tdammers 2013年

1

#ifdefのコードはばかげていませんが、悲しくてひどいです。そして、それは(今日)開発者のための診断です

さて、ジョエルは「Subversion Re-education」の論争の悪い方法(tm)で選択されました-彼は特別に選択されたユーザーで特別な縮退した状況を作成し、このユースケースを論文「Subversion suxx」の正当化として使用しました

スパゲッティコードのsuxxは、Subversionの「Right Merge」の再教育に時間を費やすよりも、管理不能で読み取り不可能なコードの方が危険です-「頻繁にマージ、モーロン!!!」分岐と双方向のマージ した、Subversionの<1.5で可能と使用可能になりましマージにもなる(mergeinfoを導入した後に)簡単に、より快適に。「興味深い」ツリーと同期マージ(多くの場合!!!)を監視することによる小さなオーバーヘッドは、開発者にとって公正な価格です。


1

彼が説明しているのは実際にはFeatureToggleであり、機能ブランチの代わりにそれを使用することには十分な理由がある可能性があります。問題はの使用#ifdefです。非常に優れた管理がなければ、コードベースのいたるところに散らかった大きな混乱になりがちです。

以下を検討してください。

  1. いつ削除し#ifdefますか?-まだその機能を除外しているビルドが残っていないことは確かですか?また、あなたが特別なビルドをする人のためのその1つの(十分にお金を払う)クライアントのためではありませんか?
  2. 誰が削除する責任があり#ifdefますか?-機能を作成した開発者ですか?彼が4週間後のことを覚えていて、スイッチがどのビルドでも除外されておらず、安全に削除できることを確認しますか?彼はそれを削除しても安全であると確信し#ifdefますか?他の非常に緊急な作業についてはどう#ifdefでしょうか。

私の経験によると、そのような#ifdefsは永遠に横たわり、ポイ捨てをするでしょう。


1

経験から(600,000行以上のコードベースの大規模なプロジェクトで、#ifdefs を使用して3年間リリースされなかった)、それらの使用に対する私の議論は次のようになります。

  • 特に、一部のIDEがインデントレベルを無視して行の先頭に配置すると主張しているため、コードの可読性が低下します。
  • それらは分離された機能に取り組んでいる開発者とそれらを回避しようとしている開発者の両方に複雑さを追加します。
  • その追加の複雑さは生産性を低下させます-私たちの場合、私はそれがプロジェクトに数ヶ月を追加したと確信しています。
  • 機能がリリースされたらそれらを削除することはゼロコストのタスクではありません。私たちの場合、誰かがすべてのを通過して削除し、#ifdefsに追加されたコードとの競合を解決するのは1週間のタスクでした#elseif

全体として、Mercurialに移行したときは輝かしい日でした-巨大で複雑すぎるコードベースがまだ残っていますが、少なくとも効率的に分岐できます。

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