この場合、clangが間違っているか、gccが間違っているか、またはその両方が間違っていますか?メンバーポインタでconstnessをキャストします

OneRaynyDay

C ++では、不変性を捨てるという概念は、標準によって厳密に定義されています。static_castおよびなどのreinterpret_castキャストは、明示的な変換で定数をキャストすることはできません。恒常性を捨てる定義は、資格変換の定義に大きく依存しています。これは、2つのタイプが同様のタイプまでの資格変換を実行できることを示しています。reinterpret_cast次に、たとえば、類似していないパーツに対してキャストを実行できます。

godboltでも利用できる例を次に示します

struct T{};
struct F{};

void f() {
    const int* const T::* const * const * const x {};
    
    // pointer to array - works in clang (trunk),
    // works in gcc (trunk)
    reinterpret_cast<int* const T::* const (*) [2]>(x);

    // member pointer to pointer - works in clang (trunk), 
    // fails in gcc (trunk)
    reinterpret_cast<int* const * const * const * const>(x);

    // member pointer to another member pointer type - fails in clang (trunk),
    // fails in gcc (trunk)
    reinterpret_cast<int* const F::* const * const * const>(x);
}

類似の定義を思い出してください。各レベルのタイプは、次のカテゴリである必要があります

...各Piは、「ポインタ」([dcl.ptr])、「タイプのクラスCiのメンバーへのポインタ」([dcl.mptr])、「Niの配列」、または「未知の境界の配列」です。 ([dcl.array])

であるために類似し、各Piは同じカテゴリに属している必要があります。

...対応するPiコンポーネントが同じであるか、1つが「Niの配列」でもう1つが「未知の境界の配列」である

最初のケースでは、配列とポインターは類似していません。GCCとclangは、型が類似X[]X*ていないことを正しく示しているreinterpret_castため、配列を超えたconst修飾子を無視するようにconst int* constなります(したがって、に変換される可能性がありますint*)。すべてが良いです。

2番目のケースでは、ポインターとメンバーポインターは類似してはなりません。clangは、型が類似していないと正しく言っているのでreinterpret_castキックインします。GCCは、型が似ていると言っているので、constnessを捨てています。ここではGCCが間違っていると確信しています。

3番目のケースでは、異なるクラスの2つのメンバーポインターを比較していますclangとGCCはどちらも類似していると考えていますが、ドラフトを注意深く見ると、「タイプのクラスCiのメンバーへのポインター」と書かれていますそれらが異なるタイプである場合、それらは類似していないと見なすべきではありませんか?ここでclangとgccの両方が間違っていますか?

ちなみに、MSVCは警告なしで上記のすべてを許可します(godboltのx64 msvc 19.27)。

編集:3番目のケースはより簡単な方法で再現できます:

const int T::* f;
reinterpret_cast<int F::*>(f);
OneRaynyDay

私はRichardSmith(clangの作成者)話し合いましたが、パスする-pedantic3つのケースすべてがコンパイルに失敗するはずであり、MSVCが実際にエラーのあるケースであるという結論に達しました。これは、reinterpret_cast <>がconstnessをキャストする各例に単一のcv-decompositionが存在するため、操作が理想的には機能しないはずであるためです。ただし、clangには、これが警告とともに機能することを可能にする拡張機能があります。それ自体はUBではありません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ