`type_alias <char [n]> {}`VS`char [N] {}`在函数的参数

时间:2018-06-04 11:34:17

标签: c++ gcc arguments clang language-lawyer

  • 环境: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
  3. type_alias很简单:

    template<typename T>
    using type_alias = T;
    

    live demon

    正如评论所述,case 1无法编译case 2

    我知道alias declarations using#define不是文字替换(如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 一个try

    case 1

    啊,海湾合作委员会给了我一个错误!然后我用两个编译器的不同版本编译它:

    • Clang foo(char[16]{}); ~~~~^ 错误消息是:
      

    prog.cc:11:11:错误:预期&#39;(&#39;用于函数式转换或类型构造

    case 2
    • Clang case 1通过。

    • GCC 禁止这两个案件通过竞争。上面列出了case 2pedantic-errors的错误消息。

    顺便说一句,对于 Clang ,我还使用case 2进行了测试,但没有任何改变。

    问题:

    • 对于case 1 Clang GCC ,谁符合标准?标准(语言律师)中的任何规范?
    • 对于case 1:谁的错误信息更正确(IOW,符合标准)?

    更新

    作为VTT评论,对于foo(const char[16]{});,它应为foo(type_alias<char[16]>{});。为这个错误道歉。

    Clang 可以编译admin: context: broadcast pattern: /admin anonymous: ~ http_basic: ~ switch_user: role: ROLE_ADMIN logout: path: /admin/logout target: / user: context: broadcast pattern: /user anonymous: ~ http_basic: ~ logout: path: /user/logout target: / 。这似乎是一个错误?

1 个答案:

答案 0 :(得分:7)

好吧,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编译,这个警告变成了错误;)。< / p>