The discussion first takes place at llvm/llvm-project#60377. After reading temp.constr.atomic and temp.constr.normal again and again, I feel even more confused about this question beacause of my poor English.
Like the example below, in order to help clang-format format requires clause correctly, I used to add a pair of bracket. Now I changed my style. When I tried to change my code, the unexpected error happened.
#include <concepts>
template <typename T>
requires std::integral<T>
struct [[nodiscard]] Widget;
template <typename T>
requires(std::integral<T>) // error: Requires clause differs
struct [[nodiscard]] Widget {
T value;
};
[[nodiscard]] auto main() -> int {
Widget<int> widget{1};
return widget.value;
}
I tested this with different compilers. It turns out:
What is the expected behaviour according to the standard, clang/msvc or gcc?
CodePudding user response:
What is the expected behaviour according to the standard, clang/msvc or gcc?
The standard does not require any particular behaviour (C 23 CD [intro.compliance.general] paragraph 2). The program is ill-formed, no diagnostic required because the validity of the program depends on whether or not the template-heads are equivalent ([basic.link] paragraph 11) and they are functionally equivalent but not equivalent ([temp.over.link] paragraph 7).