12

私たちの静的分析ツールは、次のようなヘッダー ファイルにプロトタイプがある場合、「戻り値の型の型修飾子が役に立たない」と文句を言います。

const int foo();

このように定義したのは、関数が決して変わらない定数を返しているためです。API をconst配置した方が明確に見えると考えたからです。

C標準では、明示的に初期化されていない場合、すべてのグローバルがゼロに初期化されるとすでに述べられていますが、これは明確にするためにグローバル変数を明示的にゼロに初期化することに似ているように感じます。結局のところ、それは本当に問題ではありません。(しかし、静的分析ツールはそれについて不平を言うことはありません。)

私の質問は、これが問題を引き起こす可能性がある理由はありますか? ツールによって生成されたエラーを無視する必要がありますか?それとも、明確で一貫性のない API の可能性を犠牲にしてツールをなだめる必要がありますか? const char*(ツールが問題を抱えていない他の定数を返します。)

4

6 に答える 6

26

通常は、何が起こっているかをできるだけ正確に記述した方がコードに適しています。constinconst int foo();は基本的に無意味であるため、この警告が表示されます。constキーワードの意味がわからない場合にのみ、API はより明確に見えます。そのような意味を過負荷にしないでください。staticそのままでも十分に悪いものであり、さらに混乱を招く可能性を追加する理由はありません.

const char *は意味が異なるconst intため、ツールはそれについて文句を言いません。前者は定数文字列へのポインターです。つまり、その型を返す関数を呼び出すコードは、文字列の内容を変更しようとすべきではありません (たとえば、ROM にある可能性があります)。後者の場合、システムには返された を変更しないよう強制する方法がないintため、修飾子は無意味です。戻り値の型に近いものは次のとおりです。

const int foo();
char * const foo2();

どちらも静的分析で警告が表示されます-戻り値に const 修飾子を追加することは無意味な操作です。あなたの例のように、参照パラメータ(または戻り値の型)がある場合にのみ意味がありますconst char *

実際、私は小さなテスト プログラムを作成しただけで、GCC はこの問題について明示的に警告します。

test.c:6: warning: type qualifiers ignored on function return type

したがって、不平を言っているのは静的分析プログラムだけではありません。

于 2009-10-16T17:52:40.217 に答える
5

別の手法を使用して、ツールを不快にさせずに意図を説明できます。

#define CONST_RETURN

CONST_RETURN int foo();

const char *定数ポインターではなく、定数文字へのポインターを宣言しているため、問題はありません。

于 2009-10-16T17:51:09.003 に答える
4

ここではを無視してconstfoo()値を返します。できるよ

int x = foo();

によって返された値foo()を変数xに割り当てます。これは、実行できる方法とほぼ同じです。

int x = 42;

42を変数 x に割り当てます。ただし、 ... または によって返される値
を変更することはできません。から返される値を変更できないと言って、キーワードを型に適用しても何も達成されません。42foo()foo()constfoo()

constを(またはrestrict、またはvolatile) にすることはできません。型修飾子を持つことができるのはオブジェクトだけです。


対比

const char *foo();

この場合、foo()オブジェクトへのポインターを返します。返された値が指すオブジェクトは修飾できますconst

于 2009-10-16T18:14:24.510 に答える
3

const int foo()とは大きく異なりconst char* foo()ます。 const char* foo()コンテンツの変更が許可されていない配列(通常は文字列)を返します。次の違いについて考えてください。

 const char* a = "Hello World";

const int b = 1;

aはまだ変数であり、変数ではないのに変更できない他の文字列に割り当てることができbます。それで

const char* foo();
const char* a = "Hello World\n";
a = foo();

許可されていますが

const int bar();
const int b = 0;
b = bar();

constの宣言があっても許可されませんbar()

于 2009-10-16T18:04:07.107 に答える
3

int はcopyによって返されます。これは const のコピーである可能性がありますが、それが別のものに割り当てられている場合、その何かが割り当て可能であったという事実により、その何かは定義上 const になることはできません。

キーワード const は言語内で特定のセマンティクスを持っていますが、ここでは本質的にコメントとして誤用しています。明確にするというよりは、むしろ言語のセマンティクスの誤解を示唆しています。

于 2009-10-16T18:48:28.917 に答える