ヘッダーファイルに次の関数宣言があります。
extern void flash(const char *message, const enum msg_type type);
基本的に、2つのパラメーターを取り、対応するメッセージをグローバルメッセージキューにプッシュします。パラメータを変更する必要がないため、私はそれらをconst修飾しました。ただし、CLionの静的コードアナライザーはそれについて警告を発しました。
Clang-Tidy:関数宣言でパラメーター 'type'がconst修飾されています。パラメータのconst-qualificationは関数定義にのみ影響します
これが私の質問です:
const
修飾子を指定しても効果はありません。最初のパラメーターのタイプはconst char *
、または定数文字へのポインターです。これは、変更できない文字列へのポインタを関数に渡すことができることを意味します。次に例を示します。
const char* msg = "Hello, world!";
flash(msg, SOME_MESSAGE_TYPE);
msg
の文字は変更できません。 const char
へのポインタです。パラメータタイプchar*
の関数にそれを渡すと、関数がそれらを変更する可能性があることを示します。パラメータタイプのこのconst
は呼び出し元に関連するため、保持されます。
一方、enum msg_type
は単なるenum
であり、関数にコピーされます。関数を呼び出すとき、type
を使用して関数の本体で何が発生するかは気にしません。関数の外部には影響しません。 thisがconst
であると言っても違いはないため、警告が表示されます。
最初のパラメータをconst char *const message
に変更すると、それも警告されます。これは、ポインタmessage
が指すものを変更できないことを示します。この場合も、渡されるポインタは変更されないため、呼び出し元は気にしません。
これはそれほど悪くはありません。それはあなたが混乱するかもしれないとあなたに言っています、しかしこの場合、それは何も傷つけません。ただし、警告は潜在的な問題を示し、問題のないノイズでそれらを詰まらせるだけで重要なものを読む可能性が低くなるため、警告を取り除く必要があります。
ヘッダーファイルを変更しますが、2番目のパラメーターにflash
が含まれないように、const
が実装されている場所は変更しません。それが実装されている場合は、const
を保持して、関数本体内で実際にtype
を変更しないようにしますが、宣言では必要ありません。
両方のパラメーターをconst修飾しましたが、なぜ後者のみが警告をトリガーするのですか?
警告のとおり、プロトタイプには影響しません。実装にのみ影響します。
本当に悪いのか?
それは何にも影響しないという意味ではノイズですが、それ以外は違います。
この警告を取り除くことはできますか?
const
修飾子は必要ないため、安全に削除できます。
ただし、_clang-tidy
_を使用して一般的に警告を抑制するのは少し面倒です。このリンクは役立つかもしれません:
しかし、これらの警告は実際には祝福になる可能性があります。誤ってint foo(const char *)
の代わりにint foo(char * const)
を書くことは珍しくありません。後者はこの警告をトリガーしないため、この警告が表示された場合は、何かを混同していることを示しています。