gpt4 book ai didi

c++ - 是否允许比较 static_assert 中静态类字段上的指针?

转载 作者:行者123 更新时间:2023-12-04 11:36:28 25 4
gpt4 key购买 nike

我试图在 static_assert 中验证通过比较静态字段上的指针,程序实际上具有从模板生成的两个不同的类。经过一些简化后,程序如下所示:

template<int N> struct C { 
static int x;
};

template<int N> int C<N>::x = 0;

int main() {
static_assert(&C<0>::x != &C<1>::x);
}
Clang 没问题,但 GCC 打印错误:
error: non-constant condition for static assertion
演示: https://gcc.godbolt.org/z/o6dE3GaMK
我想知道这种类型的检查是否真的允许在编译时进行?

最佳答案

这应该是比答案更多的评论,但它不适合评论部分的可读方式。
所以关于这个问题的意图:

I was trying to verify in a static_assert that a program had really two distinct classes produced from a template by comparing the pointers on their static fields


您的代码片段是一个类的模板:
template<int N> struct C { 
static int x;
};
这意味着它本身不是一个类,而是一个蓝图。实际类(class)是 C<0>C<1> .如果为 N 选择的值是不同的,那么结果类是不同的。
要确定两种类型是否不同,您将使用(正如您在评论中正确提到的那样) std::is_same_v :
static_assert( !std::is_same_v<C<0>,C<1>>);
不管 static_assert(&C<0>::x != &C<1>::x);是否有效,您不应该使用它来确定这些类型是否与语言的角度不同。在最坏的情况下,您会 - 由于请求成员的内存地址 - 阻止编译器进行一些以前可以进行的优化。

现在你可以说编译器可以基于 as-if 做优化。并在这些类型之间共享部分,因此它们在二进制级别上没有区别(语言上的不同和二进制中的不同是两个不同的东西)。
但是由于相同的 as-if,无法在代码中真正测试这些在二进制级别上的不同程度。规则。
让我们暂时假设 static_assert(&C<0>::x != &C<1>::x);会工作,然后 &C<0>::x != &C<1>::x必须评估为 true ,因为 C<0>C<1>是不同的类型。这可能是由于两件事而发生的:
  • 因为你要的是x的内存地址为 C<0>C<1>您实际上阻止编译器进行优化,然后他们将共享 x在二进制级别上,所以二进制级别上的内存地址实际上是不同的。
  • 编译器仍然进行优化,以便 xC<0> 之间共享和 C<1> .但是&C<0>::x != &C<1>::x的结果仍然是 true因为它必须是 true根据 as-if规则。所以即使地址是x对于两种不同的类型 C<0>C<1>在二进制级别上相同 static_assert测试将是 true .
  • 关于c++ - 是否允许比较 static_assert 中静态类字段上的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68987349/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com