определение функции:
void foo(const char*) {}
foo(char[16]{}); //houston, there is a problem!foo(type_alias<char[16]>{}); //compile happilytype_alias прост:
template<typename T>
using type_alias = T;
Как отмечается в комментариях, case 1 не может компилироваться, а case 2 может.
Я знаю, что alias declarations с using - это не текстовая подстановка (как #define), а синоним типа.
Но я до сих пор не могу понять, как объяснить эту ситуацию. Затем я даю GCCtry:
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]>{});
^~~~~~~~~~~~~~~~~~~~~~
А, вместо этого GCC выдал мне ошибку! Затем я компилирую его с разными версиями двух компиляторов:
case 1:prog.cc:11:11: error: expected '(' for function-style cast or type construction
foo(char[16]{}); ~~~~^
Лязг пропускает case 2.
GCC запрещает обоим двум случаям проходить соревнование. Сообщения об ошибках для case 1 и case 2 перечислены выше.
Кстати, для Лязг я также тестировал с pedantic-errors, но ничего не изменилось.
Вопросов:
case 2: Лязг, GCC, кто соответствует стандарту? Любая спецификация стандарта (юрист по языку)?case 1: чье сообщение об ошибке более правильное (IOW, соответствует стандарту)?Как комментирует VTT, для case 1 это должен быть foo(const char[16]{});. Прошу прощения за эту ошибку.
Но Лязг может скомпилировать foo(type_alias<char[16]>{});. Вроде баг?
@VTT Спасибо! Мои недостатки.





Что ж, type_alias<cv T>{} эквивалентен (cv T){}, а не cv T{}. Это различие имеет значение, когда T представляет собой массив:
foo((const char[16]){}); // OK
foo(type_alias<const char[16]>{}); // OK
foo(const type_alias<char>[16]{}); // KO
foo(const char[16]{}); // KO
Демо: https://wandbox.org/permlink/KGf3HVqN3USq6yy8
For case 2: Clang, GCC, who conforms the standard? Any spec in standard(language lawyer)?
Оба делают, оба принимают foo(type_alias<char>[16]{}), но gcc предупреждает вы об этом (и поскольку вы скомпилировали с -Werror, это предупреждение превратилось в ошибку;).
Как это объясняет, почему foo(type_alias<char[16]>{}) компилируется?
@Zereges вы можете неявно преобразовать указатель на неконстантный указатель на константу.
Я имел в виду, почему предыдущие компилируются, а foo(char[16]{}) - нет.
Кажется, что GCC выдает ошибку, а не предупреждение, посмотрите (отключите все предупреждения): wandbox.org/permlink/4cHxwKEakCw3DcS6
@ 陳 力 Ты прав oO Я думаю, это должен предупреждение. Покажи мне это.
@ 陳 力 Не знаю. Я не нашел в Стандарте ничего, что делало бы это ошибкой, но это не значит, что это не так. Надеюсь, что кто-то другой найдет это.
Разве случай 1 не должен быть
foo((const char[16]){});? Разве дополнительные скобки не требуются, потому что имя типа содержит более одного токена, как в случае сfoo((unsigned int){});?