V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wutiantong
V2EX  ›  C

msvc 到现在都没有正确实现 if constexpr

  •  
  •   wutiantong · 2018-11-13 11:08:15 +08:00 · 3009 次点击
    这是一个创建于 2201 天前的主题,其中的信息可能已经有所发展或是发生改变。

    导致我新项目的代码不能在我的 surface book2 上正确编译,sad

    第 1 条附言  ·  2018-11-13 17:17:43 +08:00
    9 条回复    2018-11-14 21:08:03 +08:00
    ysc3839
        1
    ysc3839  
       2018-11-13 14:16:36 +08:00 via Android
    wutiantong
        2
    wutiantong  
    OP
       2018-11-13 17:17:02 +08:00
    @ysc3839 我肯定开启了 c++17 支持的,你看一下这个例子: https://godbolt.org/z/MzCry0,clang 和 gcc 都没问题,msvc 就会挂的莫名其妙
    ysc3839
        3
    ysc3839  
       2018-11-13 19:00:22 +08:00 via Android
    那可能是 bug ?
    wevsty
        4
    wevsty  
       2018-11-13 21:02:52 +08:00   ❤️ 1
    稍微改了一下,在 MSVC 15.8 上加 /std:c++17 参数以后可以编译了。
    (貌似也仅有这个版本的 MSVC 才能编译)
    (当然 GCC 也可以通过编译)
    代码:
    https://godbolt.org/z/9BuPJL

    原本的代码编译过不去一方面由于 MSVC 实现的原因,另一方面这种写法本身的移植性就比较玄学。

    以下是不靠谱也不负责任的瞎掰:
    调用 get<0>()的时候因为 index 模板的特化 index<0>本身并没有 get 模板(或者叫成员函数),大概 MSVC 并不认为这样做是合法的写法所以就扔了编译错误出来。
    if constexpr 虽然是编译期决定的,但是翻了一下规定只说了 return 的返回值不参加类型推导,但是好像并没有说如果 return 的表达式本身不合法应该怎么做,那么这里就是一个未定义的灰色地带了。
    wutiantong
        5
    wutiantong  
    OP
       2018-11-13 23:16:07 +08:00
    @wevsty 感谢你提供的解决方案

    不过这个恐怕仍然是 msvc 的 BUG,可以看一下这个: https://stackoverflow.com/a/50857419
    wevsty
        6
    wevsty  
       2018-11-14 00:11:15 +08:00
    @wutiantong
    反正从现象看 MSVC 对 if constexpr 的处理上显然是要求即使被丢弃的部分也不会简单的直接跳过的。

    我个人是支持丢弃编译期就可以确定不会执行的内容的,不过这个问题可能是编译器编译逻辑或者对标准解释的问题。不太清楚 MS 是怎么考虑的,不过可以尝试给 MS 提交一下,也许下个版本他们就修过来或者给你一个解释也说不定。
    FrankHB
        7
    FrankHB  
       2018-11-14 01:30:31 +08:00   ❤️ 2
    给你报 bug 加点料:

    https://docs.microsoft.com/en-us/cpp/visual-cpp-language-conformance?view=vs-2017
    这里明确支持 P0292R2,note G 还明确 C++14 模式都行。

    http://eel.is/c++draft/stmt.if#2

    During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.

    因为你的例子中 after instantiation 以后 I 不再是 value-dependent,所以 discarded substatement 要求不能被实例化,没有什么疑问。

    很迷的是这里下面的 example 是正确的,所以不是实现策略问题,就是个 bug。

    另外注意 P0292R1 倒是没明确要求这个,但是非得说 P0292R2 嘛……。

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r2.html
    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0292r1.html
    wutiantong
        8
    wutiantong  
    OP
       2018-11-14 14:15:30 +08:00
    @FrankHB 算了,我不要去报 bug,大佬如果有兴趣的话不妨去报一下
    FrankHB
        9
    FrankHB  
       2018-11-14 21:08:03 +08:00
    之前报给 connect 的 bug 回得好好的莫名其妙就给吃了,改版以后更加尸骨无存,所以也懒得浪费时间了……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1120 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:37 · PVG 07:37 · LAX 15:37 · JFK 18:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.