代码之家  ›  专栏  ›  技术社区  ›  Chef Gladiator wds

__行在MSVC中不是constexpr

c++
  •  4
  • Chef Gladiator wds  · 技术社区  · 7 年前

    好的,最新的VS 2019社区,本地“所有默认”C++控制台项目:

    int main()
    {
        // cl Version 19.21.27702.2 for x86
        // 
        constexpr auto MSCVER = _MSC_VER; // 1921
        constexpr auto MSCFULLVER = _MSC_FULL_VER; //192127702
        constexpr auto MSCBUILD = _MSC_BUILD; // 2
        /*
        : error C2131:  expression did not evaluate to a constant
        : message :  failure was caused by non-constant arguments or reference to a non-constant symbol
        : message :  see usage of '__LINE__Var'
        */
        constexpr auto LINE = __LINE__;
    }
    

    但是似乎是Godbolt上的同一个编译器编译了这个ok。一如既往。

    https://godbolt.org/z/rn44rN

    知道吗?

    截至2019-07-22的状态

    显然,这是一个bug,这是一个特性。啊。还有一个几乎完美的宏,除了它转换为int,以及 线 很长。以下是我的版本:

    #define _DBJ_CONCATENATE_(a, b) a ## b
    #define _DBJ_CONCATENATE(a, b)  _DBJ_CONCATENATE_(a, b)
    
    #define CONSTEXPR_LINE long(_DBJ_CONCATENATE(__LINE__,U)) 
    

    原版是 here 我有几乎相同的解决方案,但我添加了一个0而不是U。可能是因为我花了几个小时试图弄清楚发生了什么。

    我很抱歉,但MSVC团队在该页面上的推理很奇怪。我想知道标准中是否有解决这个问题的细节。

    非常感谢评论者为我指出了正确的方向。但仍有一个疑问:Godbolt+MSVC为什么对同一代码没有问题?

    1 回复  |  直到 7 年前
        1
  •  4
  •   Eric Zinda    6 年前

    MSVC团队在该链接中指出,如果将“调试信息格式”从“/ZI”(用于编辑和继续的程序数据库)更改为“/ZI”(程序数据库),这也会修复它(但禁用编辑和继续)。这对我有用。

    如果您没有使用“编辑并继续”,这似乎是正确的修复方法。

        2
  •  3
  •   user10957435 user10957435    7 年前

    显然,这是 already a known issue MSVC社区:

    对于C++团队中的这个问题,我们有一个已知的bug。该开发者社区项目的状态将在查看该漏洞时更新。再次感谢您向我们报告。

    显然,它被认为是编译器的一个“功能”:

    该漏洞被认为是一个功能:编辑并继续有一小部分用户(主要是游戏开发人员)声音洪亮、热情高涨

    链接线程中的用户提供以下解决方法:

    #define CAT(X,Y) CAT2(X,Y)
    #define CAT2(X,Y) X##Y
    
    #define USABLE_LINE int(CAT(__LINE__,U)) 
    //appending 'U' shouldn't change much as __LINE__ is supposedly non-negative anyway