static_assert 和 Intel C++ 编译器

8

阅读cppreference.com:

静态断言声明可以出现在块作用域(作为块声明)和类体内部(作为成员声明)

好的,现在我有以下代码:

struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        // This is just a sample; I removed real code from this method.
        return std::max(alignof(__m128), __alignof(__m256));
    }

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message");
};

既不是MSVC 2015也不是Intel C++ 16.0.2编译这段代码(前者显示“错误C2131:表达式没有评估为常量”,后者显示“静态断言中必须具有恒定值的函数调用”错误并指向对maxAlignment的调用)。

但是MSVC 2015更新1可以编译以下代码,而Intel C++ 16.0.2不能

template <typename T, std::size_t Alignment>
struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        return std::max(std::alignment_of<T>::value, Alignment);
    }

    static_assert(0 == ((maxAlignment() -1) & maxAlignment()), "some message");
};

foo_t<__m128, 16> foo {};
// foo_t<__m128, 33> boo {};  // here `static_assert` will stop compilation

所以,当static_assert模板类体内时,MSVC可以处理它。

但以下代码被两个编译器成功编译(static_assert位于类体外部;它出现在块作用域中):

struct foo_t
{
    static constexpr std::size_t maxAlignment()
    {
        return std::max(alignof(__m128), __alignof(__m256));
    }
};

static_assert(0 == ((foo_t::maxAlignment() -1) & foo_t::maxAlignment()), "some message");

我的问题是:我有没有漏掉什么,还是这是英特尔 C++ 编译器的错误?

"MSVC 2015 成功编译了上述代码。" 在我的电脑上出现错误:"error C2131: expression did not evaluate to a constant",我在 Intel 和 GCC 上得到了相同的结果。 - zdf
@ZDF 我有“更新1”——可能这会导致MSVC 2015编译该代码(当static_assert在类体内部时)。 - Ruslan Garipov
1
编译器目前在支持constexpr方面存在很多问题;我们在GCC和MSVC中遇到了与代码生成相关的错误。 - Crashworks
1
Ruslan,我不明白。我的意思是,所有三个编译器都出现了相同的错误。@Crashworks很难相信三个编译器在同样的方面都是错误的。也许这与某些晦涩的ISO语句有关。 - zdf
1
MSVC2015-U1能够编译您的更新代码,而其他编译器不能的原因可能是这个:https://blogs.msdn.microsoft.com/vcblog/2015/12/02/constexpr-in-vs2015-update-1/。其中提到:“...我们已经修复了大约45个与constexpr使用相关的错误...在这个领域中还有大约30个错误留在我们的待办列表中...” - zdf
显示剩余4条评论
1个回答

1
如果我没记错的话,constexpr函数在完全定义之前不能使用,类成员constexpr函数在类定义之前是未定义的,这意味着你不能在类作用域内使用constexpr成员函数,其中定义了这个函数的static_assert。
但是你可以将这个函数设置为独立的(它已经是静态的),它会完成工作。它应该在任何地方都可以编译。

该函数是static的,但它取决于模板参数。 - Ruslan Garipov
@RuslanGaripov,独立函数也可能有模板参数。 - ixSci
但是ICC不能编译模板类——这个怎么办?这是编译器的错误吗? - Ruslan Garipov
1
@RuslanGaripov,我会说是的——因为所有其他编译器都可以编译它。但为了确保,我会咨询标准。 - ixSci
1
这是一个bug:https://software.intel.com/en-us/forums/intel-c-compiler/topic/610395 - Ruslan Garipov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接