`type_alias{}` VS `char[N]{}` in function

2019-06-16 19:39发布

问题:

  • Environment: x86-64 Clang 6.0.0

function's definition:

void foo(const char*) {}
  1. foo(char[16]{}); //houston, there is a problem!
  2. foo(type_alias<char[16]>{}); //compile happily

type_alias is simple:

template<typename T>
using type_alias = T;

live demon


As comment notes, case 1 cannot compile while case 2 can.

I know that alias declarations with using is not text substitution(like #define) and it is a synonym for the type.

But I still cannot figure out how to account for this situation. Then I give GCC a try:

prog.cc: In function 'int main()':
prog.cc:11:7: error: expected primary-expression before 'char'
   foo(char[16]{});
       ^~~~
prog.cc:12:7: error: taking address of temporary array
   foo(type_alias<char[16]>{});
       ^~~~~~~~~~~~~~~~~~~~~~

Ah, GCC gave me an error instead! Then I compile it with different versions of the two compilers:

  • Clang's error message for case 1 is:

prog.cc:11:11: error: expected '(' for function-style cast or type construction

foo(char[16]{});
      ~~~~^
  • Clang lets case 2 pass.

  • GCC's forbid both the two cases to pass competition. Error messages for case 1 and case 2 have been listed above.

BTW, for Clang, I have also tested with pedantic-errors, but nothing changed.


Questions:

  • For case 2: Clang, GCC, who conforms the standard? Any spec in standard(language lawyer)?
  • For case 1: Whose error message is more correct(IOW, conforms the standard)?

Update

As VTT comments, for case 1, it should be foo(const char[16]{});. Apology for this mistake.

But Clang can compile foo(type_alias<char[16]>{});. It seems to be a bug?

回答1:

Well, type_alias<cv T>{} is equivalent to (cv T){}, not to cv T{}. This distinction matters when T is an array:

foo((const char[16]){});              // OK
foo(type_alias<const char[16]>{});    // OK

foo(const type_alias<char>[16]{});    // KO
foo(const char[16]{});                // KO

Demo: https://wandbox.org/permlink/KGf3HVqN3USq6yy8


For case 2: Clang, GCC, who conforms the standard? Any spec in standard(language lawyer)?

Both does, both accept foo(type_alias<char>[16]{}), but gcc warns you about it (and since you compiled with -Werror, this warning is turned into an error ;).