gpt4 book ai didi

c++ - 为什么使用检测惯用法会导致 Clang 和 GCC 出现不同的编译错误,而 MSVC 则不会出现编译错误

转载 作者:行者123 更新时间:2023-12-02 02:17:33 25 4
gpt4 key购买 nike

在使用检测惯用语和 void_t 时,我发现涉及减法运算符和 void* 的表达式会在测试的编译器中导致不同的错误。

GCC 10.2 及更低版本,无论使用 C++11、14、17 还是 20,似乎都将某些表达式视为硬错误而不是替换失败。

我正在使用以下(精简)示例

#include <type_traits>

template< class, class, class = void >
struct has_minus_void_t : std::false_type {};
template<class T, class U>
struct has_minus_void_t<T, U, std::void_t<
decltype(T() - U())
>> : std::true_type {};

static_assert(has_minus_void_t<int*,int*>::value, "int*");
static_assert(!has_minus_void_t<int*,void*>::value, "intvoid*");
static_assert(!has_minus_void_t<void*,int*>::value, "voidint*");
static_assert(!has_minus_void_t<void*,void*>::value, "void*");

并希望代码能够针对所有四种语言标准进行正确编译(包含 C++17 之前的 std::void_t 替换,以便可以测试更多标准),但是

  • GCC 10.2 及更低版本提示最后两个断言
  • Clang 不提示
  • MSVC 提示 int*/void* 组合

我尝试搜索现有的错误报告,但找不到。

我想知道哪个编译器是正确的以及为什么。

Here's a godbolt .

最佳答案

GCC 10.2 及更早版本将 (void*)0 - (void*)0 视为硬错误而不是软错误,这是错误的。这是固定在行李箱中的。

Clang 正确执行所有操作。

MSVC 错误地允许 (int*)0 - (void*)0; (同时正确拒绝 (void*)0 - (int*)0; ),如图:

[expr.add]/2.2

For subtraction, one of the following shall hold: ...

— both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; ...

关于c++ - 为什么使用检测惯用法会导致 Clang 和 GCC 出现不同的编译错误,而 MSVC 则不会出现编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66945206/

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