`type_alias<char[N]>{}` VS `char[N]{}` in function's argument

arguments, c++, clang, gcc, language-lawyer

Solution

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 ;).

Problem

- Environment: x86-64 Clang 6.0.0 function's definition: ``` void foo(const char*) {} ``` - `foo(char[16]{}); //houston, there is a problem!` - `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?

Original source