3

静的メンバー関数がUNUSEDマクロを使用してコンパイラの警告を無効にするという問題が発生しています。マクロが有効な場合、GCC と Clang は関数を として拒否しますconstexpr。テストケースは次のとおりです。

$ cat test.cxx
#include <iostream>
#include <stdint.h>

#define UNUSED(x) ((void)x)

template <unsigned int N>
class Foo
{
public:
    enum {MIN_N=N}; enum {MAX_N=N}; enum {DEF_N=N};
    constexpr static size_t GetValidN(size_t n)
    {
        UNUSED(n); return DEF_N;
    }
};

class Bar : public Foo<16>
{
public:
    Bar(size_t n) : m_n(GetValidN(n)) {}
    size_t m_n;
};

int main(int argc, char* argv[])
{
    Bar b(10);
    return 0;
}

GCC エラー メッセージは次のとおりです。

$ g++ -std=c++11 test.cxx -o test.exe
test.cxx: In instantiation of ‘static constexpr size_t Foo<N>::GetValidN(size_t) [with unsigned int N = 16u; size_t = long unsigned int]’:
test.cxx:22:25:   required from here
test.cxx:16:5: error: body of constexpr function ‘static constexpr size_t Foo<N>::GetValidN(size_t) [with unsigned int N = 16u; size_t = long unsigned int]’ not a return-statement
     }
     ^

の使用を削除UNUSEDすると、ソース ファイルは期待どおりにコンパイルされます。

constexpr static size_t GetValidN(size_t n)
{
    return DEF_N;
}

私の知る限り、警告#define UNUSED(x) ((void)x)を抑制する唯一のポータブルな方法です。マクロは、多くのインターフェイスを持つ自明ではない C++ プロジェクトで何千もの警告を抑制するため、unused variable削除することを恐れています。監査と C&A に関連するガバナンスの問題のため、UNUSED削除できるかどうかさえわかりません。UNUSED

UNUSEDマクロを機能させて でうまくプレイするにはどうすればよいconstexprですか?


Clang は、より役立つエラー メッセージを生成します。

$ clang++ -std=c++11 test.cxx -o test.exe
test.cxx:15:2: warning: use of this statement in a constexpr function is a C++14
      extension [-Wc++14-extensions]
        UNUSED(n); return DEF_N;
        ^
test.cxx:4:19: note: expanded from macro 'UNUSED'
#define UNUSED(x) ((void)x)
                  ^
1 warning generated.

クリーンルームから生産に移行する際のもう 1 つのひねり: Doxygen。これは実際に起こることに近いので、変数名を省略することはできません。

//! \brief Returns a valid N
//! \param n a value to determine a valid N
//! \returns a valid N
constexpr static size_t GetValidN(size_t n)
{
    return DEF_N;
}
4

3 に答える 3

2

C++11 では、関数の本体にいくつかの制限がありconstexprます。

特定のケースでは、コンマ演算子を使用してそれらを克服できます。

constexpr static size_t GetValidN(size_t n)
{
    return UNUSED(n), DEF_N;
}

C++14 では、関数はそのままで問題ありません。

于 2016-09-05T06:11:00.043 に答える