29

「C++ で最も見つけにくいエラー」がおそらく存在しないことは十分に承知していますが、他の人が考えることができる/すでに遭遇した可能性があることにまだ興味があります。

この質問のアイデアは、友人との話し合いの中で生まれました。送信するソース コードに故意にエラーを含めることで、cpp プロジェクトを妨害するのはかなり簡単であることに同意しました...しかし、私たちが考えることができる最善の方法は、初期化されていない変数を使用することでした (実行時にランダムなセグメンテーション エラーにつながります)。 . もっと良い方法があると確信しています...?!

欠陥のあるコードの望ましい特性:

  • 一目で有効なコードのように見える必要があります
  • コードのコンパイルを止めてはいけません (あまりにも明白です)
  • 可能であれば、エラーは単なる間違いのように見えるはずです (発見された場合)。
  • エラーは、ソフトウェアの出荷を停止するのに十分重大でなければなりません (たとえば、ランダムなセグメント障害、コードの論理的な誤動作など)。

それでも、目立つはずですが、コードを提出した直後には明らかであってはなりません...まあ、おわかりでしょう。

心配しないでください。私たちの考慮事項は純粋に理論的なものです (プロジェクトを妨害するつもりはありません)。これは、他の人と共有するのに十分な思考実験であると単純に考えました:-)

要するに:

差分コミット (git など) では見過ごされる可能性があるが、最終的にはソフトウェアのリリースを妨げる可能性があるソースコードを妨害する最も巧妙な方法は何ですか?

4

8 に答える 8

17

クラシック:

#define if while
#define else

一部のヘッダーに埋め込まれています。


また、@WhozCraig のコメントを妨害します。

#define true (!!(__LINE__ % 10))

10行に1回trueはそうではありませんtrueが、コンパイルされたプログラムの動作は一貫性を保ちます...ソースで何かが変更されると、不可解に変化します。

この行に沿って:

#define for if(__LINE__ % 10) for

#define NULL (!(__LINE__ % 10))

またはどうですか:

#define virtual 

これは重大な問題を引き起こします - ただし、動的ディスパッチが使用されている場合のみであり、その検出がより困難になる可能性があります。


同様の方法で:

#define dynamic_cast static_cast

// Fail early, fail often
#define throw std::abort();
于 2013-01-10T23:59:44.473 に答える
15

Not too obvious:

if (foo =! foobar)

And we can add a trick to get rid of compiler warnings:

 if ( (i =! 3) && (j==1))
于 2013-01-11T00:04:44.057 に答える
9

CArrayリリース ビルドでは、 (MFC の一部として Microsoft によって) ランダムに segfault が発生するため、1 か月の大半を待たされましたが、デバッグ ビルドは問題ありませんでした。に置き換えたところstd::vector、問題は解決しました。CArray 要素代入演算子を使用せず、代わりにmemcpy ( source ) を使用することを誰かが私に通知したのは、数か月後のことでした。これにより、含まれているオブジェクトが自明でない代入演算子で明らかに破損しますが、これは標準のコンテナーであるため、誰もが安全であると想定しています。したがって、いくつかの重要な場所で に置き換えるstd::vectorCArray...

注として、Microsoft は現在、MFC コンテナーを使用せず、代わりに STL コンテナーを使用するように言っています。

于 2013-01-11T01:05:08.603 に答える
5

私にとって最も苛立たしいことは、=代わりに==. 例えば:

while(foo = bar) {}

それ以外の

while(foo == bar) {}

基本的に、コードがクラッシュする代わりに不適切に機能する原因となるものはすべて、頭を壁にぶつけてしまうことになります。

佳作:

  • 間違った数学演算子の使用- + / *
  • =vsと同様に、orを間違え==ます。&&&|||
  • 次のような時期尚早な最適化vector<bool>(「何?」のような人はここを読んでください)
  • 同じ名前のクラスが 2 つ以上あり、間違ったクラスを使用している。
于 2013-01-11T00:00:34.010 に答える
4

おそらくこの質問の恥知らずな泥棒ですが、このカテゴリーにかなり当てはまると思います。

すべて同じ長さのハードコーディングされたバイト文字列 (たとえば、ネットワークで使用するもの) がある場合は、それを偽装する機会を利用できます。

const unsigned char someBytes[] = "text\0abc123";

小さなスイッチで、次のようになります。

const unsigned char someBytes[] = "text\0123abc";

違いは、最初の文字は 12 文字ですが、2 番目の文字は 8 進数リテラルが中間にあるため、10 文字しかないことです。状況が発生した場合、これは間違いなく追跡を悪化させるでしょう.

于 2013-01-11T00:48:44.497 に答える
3

まだ犠牲になったことはありませんが、暗黙の変換はいくつかの悪いことにつながる可能性があります。これを見てください:

class Foo {
public:
    Foo(int a, OtherClass* b = NULL);
};

(明示的なキーワードなしで) 値/定数参照による Foo を期待するすべてのメソッドは、int も受け入れるようになりました!!!

于 2013-01-11T00:33:49.210 に答える
2

実際にはエラーではありませんが、リリース ビルドがデバッグ ビルドよりも遅いことが気になる場合は、ランダム ソース ファイルのどこかでこれを行います。:)

#ifdef NDEBUG
namespace {
    struct foo {
        foo() { sleep(rand() % 4); }
    } bar;
}
#endif
于 2013-01-11T01:19:48.350 に答える
2
struct
{ int foo
char bar
}


while (foobar != 10);
{
     //do something here
 } 

1) ; を入れ忘れている 構造体の後に、または ; を置きます。WILE ループの後

randn() //user created function
rand()  //library function

2) 事前定義された関数に似た名前の関数に名前を付ける

于 2013-01-11T01:05:45.860 に答える