https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98164

            Bug ID: 98164
           Summary: [C++20] The type displayed in compiler output cannot
                    be reused as displayed
           Product: gcc
           Version: 11.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: dimitri.gorokhovik at free dot fr
  Target Milestone: ---

When displaying the type of a class-type-nontype-template-argument (new with
C++20), these are shown either with parentheses '()' or with curly-brackets
'{}'.

Reusing the type as output (copy-pasting it or via automated parsing of
compiler messages), is only possible if curly-brackets '{}' are used, because
compiler considers '()' in templated types as function calls.

It would seem that the '()' and '{}' are used interchangeably, depending on
some circumstances in the source code. 

The test (compile as g++ -std=c++20 -Wall):


#include <type_traits>

struct s {};
template <auto> struct r {};

#ifdef FIX
constexpr auto P = r <s {}> {};
#endif

constexpr auto S = s {};
constexpr auto R = r <S> {};
void g ()  { using t = decltype (R);  };

static_assert (std::is_same_v <const struct r<s {}>, decltype (R)>);
// static_assert (std::is_same_v <const struct r<s ()>, decltype (R)>);

Here:
1. If FIX is not defined, the type of 't' is displayed using '()':

bug-11.cpp: In function ‘void g()’:
bug-11.cpp:12:20: warning: typedef ‘using t = const struct r<s()>’ locally
defined but not used [-Wunused-local-typedefs]
                                                              ^^
                                                              ||
   12 | void g ()  { using t = decltype (R);  };
      |                    ^

2. With -DFIX, the type is displayed using '{}' ("struct r<s{}>")
bug-11.cpp: In function ‘void g()’:
bug-11.cpp:12:20: warning: typedef ‘using t = const struct r<s{}>’ locally
defined but not used [-Wunused-local-typedefs]
                                                              ^^
                                                              ||
   12 | void g ()  { using t = decltype (R);  };

3. The last line can be un-commented to see how the compiler rejects 'const
struct r <s ()>'.


Since this choice between '()' and '{}' seem (arbitrarily?) dependent on some
external factors (which?), would it be possible to make it always use '{}'?
This would simplify creation of parsing scripts and debugging of constexpr-only
code heavily using dependent types.
  • [Bug c++/98164] New: [C++20... dimitri.gorokhovik at free dot fr via Gcc-bugs

Reply via email to