2

次のサンプル コードを使用します。

#include <string.h>
#define STRcommaLEN(str) (str), (sizeof(str)-1)

int main() {
    const char * b = "string2";
    const char * c = "string3";
    strncmp(b, STRcommaLEN(c));
}

GCC で最適化を使わない場合は問題ありませんが、-O1 以上を追加すると のようにgcc -E -std=gnu99 -Wall -Wextra -c -I/usr/local/include -O1 sample.cstrncmpマクロになり、前処理段階で STRcommaLen が展開されません。実際、結果の "code"strncmpの引数は完全に取り除かれます。

#define NEWstrncmp(a, b) strncmp (a, b)代わりに追加して使用すれば、問題は解決します。ただし、マクロになる可能性のあるすべての標準関数に独自の関数をマッピングすることは、優れた解決策とは思えません。

その原因となっている特定の最適化を見つけようとしましたが、失敗しました。実際、 -O1 を に従って有効にするすべてのフラグに置き換えるとman gcc、問題はなくなります。私の結論は、-O1 はフラグによって制御されないいくつかの最適化を追加するということです。これはその 1 つです。

一般的な方法でこの問題にどのように対処しますか? 私がよく知らないマクロマジックや、私が見ていないコンパイラフラグがあるかもしれません。多くのマクロと実質的なコード ベースがあります。このコードは、1 つの例を示すために書かれたものです。

ところで、GCC のバージョン/プラットフォームはgcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5).

ありがとう、アレン

4

1 に答える 1

1

あなたは正しくそれを指摘しました

前処理段階で STRcommaLen は展開されません

- より正確には、strncmpマクロが展開される前ではありません。これは必然的に、おそらく見落としたり、言及するのを忘れたりしたエラーにつながります。

sample.c:7:30: error: macro "strncmp" requires 3 arguments, but only 2 given

あなたの結論

その -O1 は、フラグによって制御されないいくつかの最適化を追加します。これはその1つです

これも正しいです - これは__OPTIMIZE__明らかに によって設定されるマクロによって制御され-O1ます。

私がそのようなことをしたとしても(あなたがsizeofaを使用して示した落とし穴に関しては、おそらくそうしないでしょうchar *)、私はまだ選択します

マクロになる可能性のあるすべての標準関数に独自の関数をマッピングする

-しかしむしろ好き

#include <string.h>
#define STRNCMP(s1, s2) strncmp(s1, s2, sizeof(s2)-1)

int main()
{
    const char b[] = "string2";
    const char c[] = "string3";
    STRNCMP(b, c);
}
于 2014-07-04T06:33:25.233 に答える