两个不指向同一数组或同一对象(包括数组/对象的后一者)的非空指针相减是未定义的行为,请参阅[表达式.添加] https://timsong-cpp.github.io/cppwp/n4659/expr.addC++17 标准(最终草案)的(特别是第 5 段和第 7 段)。
Expressions which would have core undefined behavior[1] if evaluated are never constant expressions, see [expr.const]/2.6 https://timsong-cpp.github.io/cppwp/n4659/expr.const#2.6.
所以type_pointer<int> - type_pointer<float>
不能是常量表达式,因为这两个指针指向不相关的对象。
Since type_pointer<int> - type_pointer<float>
不是常量表达式,它不能用于初始化constexpr
变量如
constexpr auto x = type_pointer<int> - type_pointer<float>;
尝试使用非常量表达式作为初始化constexpr
变量使程序格式错误,并要求编译器打印诊断消息。这就是您看到的错误消息。
基本上,当核心未定义行为出现在纯编译时上下文中时,编译器需要对其进行诊断。
您可以看到,如果指针指向同一个对象,则不会出现错误,例如:
constexpr auto x = type_pointer<int> - type_pointer<int>;
这里的减法是明确定义的,并且初始化器是一个常量表达式。因此代码将编译(并且不会有未定义的行为)。x
将有一个明确定义的值0
.
请注意,如果您使x
non-constexpr
编译器将不再需要诊断未定义的行为并打印诊断消息。因此它可能会编译。
减去不相关的指针仍然是不明确的但行为不仅未指定行为。因此,您将失去对最终程序的功能的任何保证。这不仅意味着您将获得不同的值x
在代码的每次编译/执行中。
[1] Core undefined behavior here refers to undefined behavior in the core language, in contrast with undefined behavior due to use of the standard library. It is unspecified whether undefined behavior as specified for the library causes an (otherwise constant) expression to not be a constant expression, see final sentence before the example in [expr.const]/2 https://timsong-cpp.github.io/cppwp/n4659/expr.const#2.22.