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

一个 msvc 与 gcc/clang 不一致的例子,哪边是对的?

  •  
  •   wutiantong · 2020-11-25 14:16:58 +08:00 · 2438 次点击
    这是一个创建于 1220 天前的主题,其中的信息可能已经有所发展或是发生改变。

    下面的代码基于 C++17,msvc 是最新版本的( 16.8.2 ),gcc/clang 也是最新版本的,可在线运行:godblot

    namespace user
    {
        template<typename T> const T unit { 1 };
    
        template<typename Def>
        struct data
        {
            typename Def::value_type val;
        };
        template<typename Def> const data<Def> unit<data<Def>> { Def::unit_val() };
    
        struct decimal_def
        {
            using  value_type = int;
            static value_type unit_val() noexcept { return 10; }
        };
        using decimal_data = data<decimal_def>;
        inline const auto decimal_data_unit = unit<decimal_data>;
    }
    
    #include <iostream>
    int main()
    {
        std::cout << user::decimal_data_unit.val << std::endl;
    }
    
    

    预期输出:10

    msvc 输出:0

    gcc/clang 输出:10

    5 条回复    2020-11-26 13:27:32 +08:00
    wutiantong
        1
    wutiantong  
    OP
       2020-11-25 15:10:13 +08:00
    顺带提一下,这样修改可以使 msvc 的输出符合预期:

    inline const auto & decimal_data_unit = unit<decimal_data>;

    主要想讨论一下,上面的写法是否有问题,还是编译器的 bug ?
    lcdtyph
        2
    lcdtyph  
       2020-11-25 16:14:11 +08:00
    static constexpr value_type unit_val() noexcept { return 10; }
    wutiantong
        3
    wutiantong  
    OP
       2020-11-25 16:50:29 +08:00
    @lcdtyph 确实是 work 的,而且我发现问题还跟 data 的构造函数有关:

    如果给 data 上一个普通的构造函数,结果又不行了(变成 0 ),需要再进一步把构造函数修饰成 constexpr (这也说明例子中原本默认的 aggregate 构造函数是 constexpr,但我好像没找到标准说明?)

    所以问题是,这个行为到底是 msvc 比较正确还是 gcc 比较正确呢?
    lcdtyph
        4
    lcdtyph  
       2020-11-25 17:29:10 +08:00 via iPhone
    @wutiantong
    我对标准了解的不深,说不上哪边是对的…我也没有 msvc 环境,上面的修改是根据经验改的😂

    不过从你描述的现象来看,msvc 需要触发 unit 的实例化才能输出期望的结果。
    Wirbelwind
        5
    Wirbelwind  
       2020-11-26 13:27:32 +08:00
    @wutiantong 不是构造函数的问题

    在初始化的时候需要调用 unit_val(),问题是编译器 什么时候 用 unit_val()的返回值对它赋值
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2878 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:20 · PVG 19:20 · LAX 04:20 · JFK 07:20
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.