0

私はC数学ライブラリに取り組んでおり、ほとんどの作業にマクロを使用していますが、現在問題に直面しています。

マクロは次のようになります。

the_macro(a, b, c)

マクロ自体は次のようなことをします。 (a - b > 0) ? error_function : 1

error_functionは、準拠時にユーザーを停止するために使用されます。したがって、の場合、マクロ(a - b > 0)true定義のない関数として展開されます。したがって、これによりリンケージエラーが発生します。

すべてが良さそうですが、今日、上司から単体テストを行う必要があると言われたので、マクロをラップする関数を作成しました。

int my_func(int a, int b, int c)
{
    return the_macro(a, b, c);
}

ここで問題が発生します。コードはリンケージを渡すことができません。定数の代わりにvarを使用してthe_macroを呼び出すと、これらerror_functions.oファイルに含まれるため、int a, int b, int c実行時にすべて既知であるため、マクロ関数のみを呼び出すことができます。定数付き:the_macro(2, 3, 4)これを回避する方法はありますか?または、このマクロで単体テストを実行するためのより良い解決策はありますか?

編集:

私が取り組んでいるコードは機密情報です...しかし、問題を示す例を作成しました。

#include <stdio.h>

#define the_macro(a, b)\
    (a > b)?error_function():1

// Comment out my_func(), then the program will run normaly
// But if you don't comment it out, the linkage error will come out.
void my_func(int a, int b)
{
    the_macro(a, b);
}

int main()
{
    printf("%d\n", the_macro(1, 10));
    return 0;
}

gcc-4を使用しています

4

4 に答える 4

4

マクロを使用する場所に関係なく、error_function宣言されていない場合は、コンパイラエラーが発生するはずです。宣言されているが定義されていない場合、未定義の動作があります。マクロへの引数が定数であるかどうかは、この点で何も変わりません。(未定義の動作の場合、実際の動作に影響を与える可能性があります。)

于 2012-06-08T07:48:25.363 に答える
2

定数を使用してマクロを呼び出すと、コンパイラは値を認識します。したがって、おそらく最適化として、式はの代わりににthe_macro (5, 4, 0)置き換えられます。式がに評価されると、コンパイラはそれをに置き換え、コンパイルを停止します。1error_functiona-b<= 0error_function

一方、変数を使用する場合、コンパイラは式の結果を認識せず、未定義の関数の呼び出しを含むマクロの完全な展開を使用する必要があるため、リンケージエラーが発生します。

于 2012-06-08T07:46:02.863 に答える
1

単体テスト(のみ)の目的で、単体テストのerror_function()一部として定義し、テストフレームワークが検出できるエラーを無条件に返すようにします。そうすれば、定数または変数のいずれかを使用して、コンパイル時に表示される動作を模倣できるはずです。

正確には望みどおりではありませんが、単体テストフレームワークは、その性質上、ランタイムテストメカニズムであるため、自動コンパイル時テストはおそらく不可能です。

system()または、ライブラリを含むコマンドラインビルドを実行し、エラーを含む出力をファイルにリダイレクトするために使用することもできます。次に、ファイルを開いて、リンケージエラーの既知のテキストをスキャンします。

于 2012-06-08T07:47:04.257 に答える
1

私がこれを正しく理解しているかどうか見てみましょう:

次の場合にコンパイルを中断する方法が必要a-b>0ですか?C11を使用しない限り、これは実際には不可能です。条件に応じてコンパイラを中止させる方法はありません。あなたの場合、オプティマイザーとリンカーの組み合わせを使用して、目的の動作を実現しようとしています。しかし、これは確実に機能しません。

ab> 0の場合、式はオプティマイザーによって1に減らされる可能性がありますが、これは保証されません(a - b > 0) ? error_function : 1 コンパイラがC標準によって定義されていることを示さなければならないことが保証された動作があり、この標準はオプティマイザについて言及していません。同じオプティマイザが式を減らす場合もあれば、コード内の他のものによっては式を減らすことができない場合もあります。または、渡すコマンドラインフラグに応じて、削減される場合と削減されない場合があります。

したがって、このマクロを使用すると、コードを記述していることになります。コードは、コンパイラ、コンパイラバージョン、オペレーティングシステムを切り替えたり、リンクされたライブラリやターゲットアーキテクチャを追加または削除したりすると、突然破損する可能性があります。そのような変更に応じて突然壊れてしまうコードは非常に悪いです。あなたの仲間の開発者にこれをしないでください。

標準に準拠しているため、将来のコンパイラが確実に理解できるポータブルコードを作成することをお勧めします。C11より前では、これを行う方法はありません。これが本当に必要な場合static_assertは、コンパイルを条件付きで中止できるキーワードを持つC11を使用するしか方法がないことを上司に伝えてください。

于 2012-06-08T07:59:39.447 に答える