为什么这个模板参数推导在 GCC 而不是 Clang 上失败?
Why does this template argument deduction fail on GCC but not Clang?
我将 Clang 和 GCC 主干与 -std=c++20
一起使用,以下代码在 Clang 上编译正常,但在 GCC 上编译失败。
#include <cstdint>
#include <climits>
#include <type_traits>
#include <concepts>
#include <immintrin.h>
#define VECTOR_SIZE 32
template <typename T> requires std::is_arithmetic_v<T>
using vec __attribute__((__vector_size__(VECTOR_SIZE))) = T;
template <std::unsigned_integral T>
constexpr vec<T> rotl(vec<T> x, int k)
{
constexpr auto N = CHAR_BIT * sizeof(T);
return (x << k) | (x >> (N - k));
}
template <std::unsigned_integral T>
constexpr vec<T> rotr(vec<T> x, int k)
{
constexpr auto N = CHAR_BIT * sizeof(T);
return (x >> k) | (x << (N - k));
}
vec<uint32_t> test(vec<uint32_t> x)
{
return rotr(x, 7);
}
GCC 错误:
x86-64 gcc (trunk) (Editor #1, Compiler #1) C++#1 with x86-64 gcc (trunk)
<source>: In function 'vec<unsigned int> test(vec<unsigned int>)':
<source>:27:20: error: no matching function for call to 'rotr(vec<unsigned int>&, int)'
27 | return rotr(x, 7);
| ~~~~^~~~~~
<source>:19:22: note: candidate: 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int)'
19 | constexpr vec<T> rotr(vec<T> x, int k)
| ^~~~
<source>:19:22: note: template argument deduction/substitution failed:
<source>:19:22: note: constraints not satisfied
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts: In substitution of 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int) [with T = __vector(8) unsigned int]':
<source>:27:20: required from here
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:13: required for the satisfaction of 'integral<_Tp>' [with _Tp = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:108:13: required for the satisfaction of 'unsigned_integral<T>' [with T = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:24: note: the expression 'is_integral_v<_Tp> [with _Tp = __vector(8) unsigned int]' evaluated to 'false'
102 | concept integral = is_integral_v<_Tp>;
| ^~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
<source>: In function 'vec<unsigned int> test(vec<unsigned int>)':
<source>:27:20: error: no matching function for call to 'rotr(vec<unsigned int>&, int)'
27 | return rotr(x, 7);
| ~~~~^~~~~~
<source>:19:22: note: candidate: 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int)'
19 | constexpr vec<T> rotr(vec<T> x, int k)
| ^~~~
<source>:19:22: note: template argument deduction/substitution failed:
<source>:19:22: note: constraints not satisfied
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts: In substitution of 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int) [with T = __vector(8) unsigned int]':
<source>:27:20: required from here
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:13: required for the satisfaction of 'integral<_Tp>' [with _Tp = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:108:13: required for the satisfaction of 'unsigned_integral<T>' [with T = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:24: note: the expression 'is_integral_v<_Tp> [with _Tp = __vector(8) unsigned int]' evaluated to 'false'
102 | concept integral = is_integral_v<_Tp>;
| ^~~~~~~~~~~~~~~~~~
Execution build compiler returned: 1
我怀疑它是模板参数推导中的 GCC 错误,由您的别名与向量内在属性 组合而成:
- 如果您 specify the template argument of
rotr
手动编译它。
- C++17 中没有概念的简化示例也可以在 Clang and Intel compiler but yet again fails on GCC 上编译。因此 C++20
concepts
不可能是原因!
- 如果你只用一个简单的
struct vec
. 交换别名,它编译得很好
因此,没有模板参数推导的代码本身似乎是完全有效的,只是 GCC 以某种方式最终推导了 T = __vector(8) unsigned int
,然后 std::unsigned_integral<T>
概念失败,因为 is_integral_v<T>
计算为 false
.
我想为了得到一个更好的答案来解释为什么会发生这种情况,您需要 language-lawyer
。
我将 Clang 和 GCC 主干与 -std=c++20
一起使用,以下代码在 Clang 上编译正常,但在 GCC 上编译失败。
#include <cstdint>
#include <climits>
#include <type_traits>
#include <concepts>
#include <immintrin.h>
#define VECTOR_SIZE 32
template <typename T> requires std::is_arithmetic_v<T>
using vec __attribute__((__vector_size__(VECTOR_SIZE))) = T;
template <std::unsigned_integral T>
constexpr vec<T> rotl(vec<T> x, int k)
{
constexpr auto N = CHAR_BIT * sizeof(T);
return (x << k) | (x >> (N - k));
}
template <std::unsigned_integral T>
constexpr vec<T> rotr(vec<T> x, int k)
{
constexpr auto N = CHAR_BIT * sizeof(T);
return (x >> k) | (x << (N - k));
}
vec<uint32_t> test(vec<uint32_t> x)
{
return rotr(x, 7);
}
GCC 错误:
x86-64 gcc (trunk) (Editor #1, Compiler #1) C++#1 with x86-64 gcc (trunk)
<source>: In function 'vec<unsigned int> test(vec<unsigned int>)':
<source>:27:20: error: no matching function for call to 'rotr(vec<unsigned int>&, int)'
27 | return rotr(x, 7);
| ~~~~^~~~~~
<source>:19:22: note: candidate: 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int)'
19 | constexpr vec<T> rotr(vec<T> x, int k)
| ^~~~
<source>:19:22: note: template argument deduction/substitution failed:
<source>:19:22: note: constraints not satisfied
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts: In substitution of 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int) [with T = __vector(8) unsigned int]':
<source>:27:20: required from here
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:13: required for the satisfaction of 'integral<_Tp>' [with _Tp = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:108:13: required for the satisfaction of 'unsigned_integral<T>' [with T = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:24: note: the expression 'is_integral_v<_Tp> [with _Tp = __vector(8) unsigned int]' evaluated to 'false'
102 | concept integral = is_integral_v<_Tp>;
| ^~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 1
<source>: In function 'vec<unsigned int> test(vec<unsigned int>)':
<source>:27:20: error: no matching function for call to 'rotr(vec<unsigned int>&, int)'
27 | return rotr(x, 7);
| ~~~~^~~~~~
<source>:19:22: note: candidate: 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int)'
19 | constexpr vec<T> rotr(vec<T> x, int k)
| ^~~~
<source>:19:22: note: template argument deduction/substitution failed:
<source>:19:22: note: constraints not satisfied
In file included from <source>:3:
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts: In substitution of 'template<class T> requires unsigned_integral<T> constexpr vec<T> rotr(vec<T>, int) [with T = __vector(8) unsigned int]':
<source>:27:20: required from here
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:13: required for the satisfaction of 'integral<_Tp>' [with _Tp = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:108:13: required for the satisfaction of 'unsigned_integral<T>' [with T = __vector(8) unsigned int]
/opt/compiler-explorer/gcc-trunk-20210524/include/c++/12.0.0/concepts:102:24: note: the expression 'is_integral_v<_Tp> [with _Tp = __vector(8) unsigned int]' evaluated to 'false'
102 | concept integral = is_integral_v<_Tp>;
| ^~~~~~~~~~~~~~~~~~
Execution build compiler returned: 1
我怀疑它是模板参数推导中的 GCC 错误,由您的别名与向量内在属性 组合而成:
- 如果您 specify the template argument of
rotr
手动编译它。 - C++17 中没有概念的简化示例也可以在 Clang and Intel compiler but yet again fails on GCC 上编译。因此 C++20
concepts
不可能是原因! - 如果你只用一个简单的
struct vec
. 交换别名,它编译得很好
因此,没有模板参数推导的代码本身似乎是完全有效的,只是 GCC 以某种方式最终推导了 T = __vector(8) unsigned int
,然后 std::unsigned_integral<T>
概念失败,因为 is_integral_v<T>
计算为 false
.
我想为了得到一个更好的答案来解释为什么会发生这种情况,您需要 language-lawyer
。