`type_alias{} `VS` char [N] {} `в аргументе функции - PullRequest
0 голосов
/ 04 июня 2018
  • Среда: x86-64 Clang 6.0.0

Определение функции:

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

type_alias просто:

template<typename T>
using type_alias = T;

live demon


Как отмечается в комментариях, case 1 не может скомпилироваться, в то время как case 2 может.

Я знаю, что alias declarations с using не является подстановкой текста (например, #define), и это синоним для типа.

Но я до сих пор не могу понять, как объяснить эту ситуацию.Тогда я даю 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]>{});
       ^~~~~~~~~~~~~~~~~~~~~~

Ах, GCC дал мне ошибку вместо!Затем я компилирую его с разными версиями двух компиляторов:

  • Clang Сообщение об ошибке для case 1:

prog.cc:11:11: ошибка: ожидается '(' для приведения типа функции или построения типа

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

  • GCC запрещают оба эти случая для прохождения соревнования. Сообщения об ошибках для case 1 и case 2 были перечислены выше.

Кстати, для Clang , я также тестировал с pedantic-errors, но ничего не изменилось.


Вопросы:

  • Для case 2: Clang , GCC , кто соответствует стандарту? Любая спецификация в стандарте (язык юрист)?
  • Для case 1:Чье сообщение об ошибке более корректно (IOW, соответствует стандарту)?

Обновление

Как отмечает VTT, для case 1 должно быть foo(const char[16]{});. Извинение за эту ошибку.

Но Clang может компилировать foo(type_alias<char[16]>{});.кажется, ошибка?

1 Ответ

0 голосов
/ 04 июня 2018

Ну, 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


Для случая 2: Clang, GCC, кто соответствует стандарту?Любая спецификация в стандарте (адвокат по языку)?

Оба делают, оба принимают foo(type_alias<char>[16]{}), но gcc предупреждает вас об этом (и так как вы скомпилировали с -Werror, этопредупреждение превращается в ошибку;).

...