web-dev-qa-db-ja.com

関数宣言のパラメーターの定数修飾

ヘッダーファイルに次の関数宣言があります。

extern void flash(const char *message, const enum msg_type type);

基本的に、2つのパラメーターを取り、対応するメッセージをグローバルメッセージキューにプッシュします。パラメータを変更する必要がないため、私はそれらをconst修飾しました。ただし、CLionの静的コードアナライザーはそれについて警告を発しました。

Clang-Tidy:関数宣言でパラメーター 'type'がconst修飾されています。パラメータのconst-qualificationは関数定義にのみ影響します

enter image description here

これが私の質問です:

  1. 両方のパラメーターをconst修飾しましたが、なぜ後者のみが警告をトリガーするのですか?
  2. 本当に悪いのか?効果がないことはわかっていますが、技術的にはconst修飾子を指定しても効果はありません。
  3. この警告を取り除くことはできますか?
10
nalzok

最初のパラメーターのタイプはconst char *、または定数文字へのポインターです。これは、変更できない文字列へのポインタを関数に渡すことができることを意味します。次に例を示します。

const char* msg = "Hello, world!";
flash(msg, SOME_MESSAGE_TYPE);

msgの文字は変更できません。 const charへのポインタです。パラメータタイプchar*の関数にそれを渡すと、関数がそれらを変更する可能性があることを示します。パラメータタイプのこのconstは呼び出し元に関連するため、保持されます。

一方、enum msg_typeは単なるenumであり、関数にコピーされます。関数を呼び出すとき、typeを使用して関数の本体で何が発生するかは気にしません。関数の外部には影響しません。 thisconstであると言っても違いはないため、警告が表示されます。

最初のパラメータをconst char *const messageに変更すると、それも警告されます。これは、ポインタmessageが指すものを変更できないことを示します。この場合も、渡されるポインタは変更されないため、呼び出し元は気にしません。


これはそれほど悪くはありません。それはあなたが混乱するかもしれないとあなたに言っています、しかしこの場合、それは何も傷つけません。ただし、警告は潜在的な問題を示し、問題のないノイズでそれらを詰まらせるだけで重要なものを読む可能性が低くなるため、警告を取り除く必要があります。


ヘッダーファイルを変更しますが、2番目のパラメーターにflashが含まれないように、constが実装されている場所は変更しません。それが実装されている場合は、constを保持して、関数本体内で実際にtypeを変更しないようにしますが、宣言では必要ありません。

8
Daniel H

両方のパラメーターをconst修飾しましたが、なぜ後者のみが警告をトリガーするのですか?

警告のとおり、プロトタイプには影響しません。実装にのみ影響します。

本当に悪いのか?

それは何にも影響しないという意味ではノイズですが、それ以外は違います。

この警告を取り除くことはできますか?

const修飾子は必要ないため、安全に削除できます。

ただし、_clang-tidy_を使用して一般的に警告を抑制するのは少し面倒です。このリンクは役立つかもしれません:

clang-tidy:警告を抑制する方法は?

しかし、これらの警告は実際には祝福になる可能性があります。誤ってint foo(const char *)の代わりにint foo(char * const)を書くことは珍しくありません。後者はこの警告をトリガーしないため、この警告が表示された場合は、何かを混同していることを示しています。

3
klutt