C++標準の達人が私を教えてくれませんか:
(v)
が(*&v)
と同等であると思われるため、このステートメントが失敗したC++標準バージョンはどれですか。
つまりたとえば、コード:
#define DEC(V) ( ((V)>0)? ((V)-=1) : 0 )
...{...
register int v=1;
int r = DEC(v) ;
...}...
これにより、-std=c++17
の下に次のような警告が生成されるようになりました。
レジスタ変数のアドレスを取得できません
オペランドの左側は左辺値でなければなりません
多くのCマクロは、すべてのマクロパラメータを括弧で囲んでいますが、上記は代表的な例にすぎません。
警告を生成する実際のマクロは、たとえばRTA_*
マクロin/usr/include/linux/rtnetlink.h
です。
C++でこれらのマクロを使用/再定義しない以外に、回避策はありますか?
最新のC++ 1zドラフトのリビジョンの概要を見ると、これは [diff.cpp14.dcl.dcl] にあります。
[dcl.stc]
変更:レジスタstorage-class-specifierの削除。
根拠:この国際規格の将来の改訂で非推奨のキーワードの転用を有効にします。
元の機能への影響:レジスタstorage-class-specifierを使用する有効なC++ 2014宣言は、この国際標準では不正な形式です。指定子は、元の意味を保持するために簡単に削除できます。
警告はそれが原因である可能性があります。
register
はストレージクラス指定子ではなくなったため、削除する必要があります。コンパイラは正しいエラーや警告を発行していない可能性がありますが、コードの先頭にregister
を含めることはできません。
以下は、コード内のregister
に関して何をすべきかを人々に知らせる標準からの引用です(関連部分が強調されています)、おそらくそのファイルの古いバージョンがあります
C.1.6条項10:宣言[diff.dcl]
変更:C++では、レジスターはストレージクラス指定子ではありません。
理論的根拠:ストレージクラス指定子はC++では効果がありませんでした。元の機能への影響:意味的に明確に定義された機能の削除。
変換の難しさ:構文変換。
広く使用されている方法:一般的。
問題のファイルには実際にはregister
キーワードが含まれていないため、心配する必要はありません。
grep "register" /usr/include/linux/rtnetlink.h
何も出力しません。いずれにせよ、次の理由で警告を受け取るべきではありません。
少なくともGCCでは、システムヘッダーはデフォルトで警告を発しません
微妙で厄介な重大な変更がある可能性があるため、Linuxカーネルのようなシステムプロジェクトに属するファイルをC++モードでコンパイルしようとするのは賢明ではありません。
通常どおりファイルを含めるか、CコードをC++バイナリにリンクします。通常はコンパイラベンダーに抑制すべき警告が実際に表示される場合は、バグを報告してください。