質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

MSVC?のconstexprの挙動について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,147

score 8

constexprの挙動について

Visual Studio 2019を用いてenumを管理するようなプログラムをC++14で書いたのですが、constexprとそうでないものの結果が異なり困っています。なお、Wandboxを使ってGCCとClangで試してみたところ、結果は同じ(どちらも1)でした。
実行時のデバッグでは正しい値が帰ってくるのですが、肝心なコンパイル時にどういう挙動をしているかをのぞけないため、解決できずに質問した次第です。
解決策等ご教示いただけると幸いです。

該当のソースコード

*タイムアウトしたためリンクが変更されています。また、期間を延ばしました*
* ヘッダファイル側:Pastebin *

enum class test
{
    v0, v1, v2, v4 = 4, v8 = 8, v16 = 16, v32 = 32
};
ENUM2_ENUM(test)
constexpr inline decltype(auto) get_flags(test) noexcept
{
    using enum2::blk;
    return enum2::blk_cat(
        blk(test::v1, 100, test::v2, test::v4, test::v32), //test::v1とtest::v2,test::v4,test::v32は共存できない
        blk(enum2::force_or(test::v2, test::v4), 100, false, test::v8),//test::v2とtest::test::v4はtest::v8と共存できない
        blk(enum2::force_or(test::v16, test::v2), 100, test::v32)  //(test::v16|test::v2)はtest::v32とは共存できない
    );
}
#include <iostream>

int main()
{
    constexpr test v0 = test::v0 | test::v1 | test::v2; //3
    test v1 = test::v0 | test::v1 | test::v2; //1

    std::cout << static_cast<int>(v0) << static_cast<int>(v1);

    return 0;
}
MSVCの情報

Microsoft Visual Studio Community 2019
Version 16.2.3
VisualStudio.16.Release/16.2.3+29215.179
Microsoft .NET Framework
Version 4.7.03062

インストールされているバージョン:Community

Visual C++ 2019   00435-60000-00000-AA041
Microsoft Visual C++ 2019
(以下略)

追記

「結果が異なる」のはconstexpr側では結果が3、そうでない側では1(意図した結果)になります。

追記2

pastebinのリンクがタイムアウトしてしまった(一日経過してしまった)ので更新しました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • y_waiwai

    2019/08/28 21:33

    どういうふうに結果が違うんでしょうか

    キャンセル

  • aptx42

    2019/08/28 21:39

    ご返信ありがとうございます。
    constexpr側では結果が3、そうでない側では1(意図した結果)になります。(コメントにてうっすら書いたのですが、わかりにくくて申し訳ないです)

    キャンセル

  • SHOMI

    2019/08/29 00:25 編集

    constexpr test_holder v0 = test::v0 | test::v1 | test::v2;
    とするとtest::v1になりますね…
    (追記)
    すみません、IntelliSense上ではtest::v1になっていましたが、実際は3でした…

    キャンセル

  • aptx42

    2019/08/29 15:12

    検証感謝いたします。こちらの環境もIntelliSenseは正しい値を認識できているのですがうーん

    キャンセル

回答 2

check解決した方法

+2

バグレポ(クソ英語注意)コンパイル時にSwallowを正しく評価できないMSVCのバグだったようです。お騒がせしました

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

たぶんtest v0 =ではなくtest_holder v0 =としないといけないと思います。

    constexpr auto v0 = test::v0 | test::v1 | test::v2; //3
    auto v1 = test::v0 | test::v1 | test::v2; //1


と、autoで推論させると、v0とv1はtest_holderになります。
こうすると結果は共に「1」になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/06 18:31

    回答ありがとうございます。autoで型推論(=test_holder)にすると出力結果が1になるのは、おそらくholderにoperator bool()が定義されているためです。実際
    ```c++
    auto kx = (test::v1 | test::v8) & test::v8;
    std::cout << static_cast<int>(kx);
    ```
    こういうコードを書くと出力は1(8!=0であるから)となります。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る