【问题标题】:Expected expression before 'typeof' OR expected primary-expression before 'typeof''typeof' 之前的预期表达式或 'typeof' 之前的预期主表达式
【发布时间】:2016-07-26 13:18:09
【问题描述】:

我有一个这样的宏:

#include <stdio.h>
#include <stddef.h>

#define m_test_type(e)                              \
    do {                                            \
         if (typeof(e) == typeof(char [])) {        \
            printf("type is char []\n");            \
         } else                                     \
         if (typeof(e) == typeof(int)) {            \
            printf("type is int\n");                \
         } else {                                   \
            printf("type is unknown\n");            \
         }                                          \
     } while (0)

int main() {
    char s[] = "hello";

    m_test_type(s);

    return 0;
}

在使用 gcc 编译时出现以下错误:

prog.cpp: In function 'int main()':
prog.cpp:6:14: error: expected primary-expression before 'typeof'
          if (typeof(e) == typeof(char *)) {         \
              ^
prog.cpp:19:2: note: in expansion of macro 'm_test_type'
  m_test_type(s);
  ^
prog.cpp:6:14: error: expected ')' before 'typeof'
          if (typeof(e) == typeof(char *)) {         \
              ^
prog.cpp:19:2: note: in expansion of macro 'm_test_type'
  m_test_type(s);
  ^
prog.cpp:9:14: error: expected primary-expression before 'typeof'
          if (typeof(e) == typeof(int)) {            \
              ^
prog.cpp:19:2: note: in expansion of macro 'm_test_type'
  m_test_type(s);
  ^
prog.cpp:9:14: error: expected ')' before 'typeof'
          if (typeof(e) == typeof(int)) {            \
              ^
prog.cpp:19:2: note: in expansion of macro 'm_test_type'
  m_test_type(s);
  ^

【问题讨论】:

  • typeof 不是标准 C,它是 GCC 中的 GNU extension。你用的是什么编译器?
  • 我正在使用 gcc 编译器
  • 代码必须采用 e 的 SWAG。它没有办法知道,typeof也没有。
  • typeof 不产生值,它产生一个类型。您无法比较类型。例如if (int == int) 是无效的比较。
  • 摇摆的野驴猜......

标签: c gcc macros


【解决方案1】:

我认为您不能使用 typeof 来测试类型是否相等。如果你查看gcc manualtypeof (expr) 被静态替换为表达式的类型,它允许你声明变量:

int i;
typeof(&i) p; 

在这种情况下,最后一条指令将等同于int* p;

但是,如果您在像您这样的 if 语句中使用 typeof 将是一个错误,因为它相当于编写类似

的内容
if ( char* == char *)

这是导致错误的原因。

【讨论】:

    【解决方案2】:

    这不是标准的 C,因此它只能通过 GCC 设置编译为非标准编译器。这意味着您可能不应该使用-std=c11-pedantic 之类的选项来进行编译。不过我不建议这样做。

    我会建议摆脱所有非标准的 GCC 废话,改为编写纯标准 C:

    #include <stdio.h>
    
    #define m_test_type(e)                     \
      printf(_Generic((e),                     \
               char*:   "type is char*\n",     \
               int:     "type is int\n",       \
               default: "type is unknown\n"    \
             ));
    
    int main() {
        char s[] = "hello";
    
        m_test_type(s);
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      我现在可以使用builtin functions 运行此代码:

      #include <stdio.h>
      
      #define m_test_type(e)                                                   \
          do {                                                                 \
               if (__builtin_types_compatible_p(typeof(e), typeof(char []))) { \
                  printf("type is char []\n");                                 \
               } else                                                          \
               if (__builtin_types_compatible_p(typeof(e), typeof(int))) {     \
                  printf("type is int\n");                                     \
               } else {                                                        \
                  printf("type is unknown\n");                                 \
               }                                                               \
           } while (0)
      
      int main() {
          const char s[] = "hello";
      
          m_test_type(s);
      
          return 0;
      }
      

      【讨论】:

      • 但是当类型实际上是 char [] 时,您正在打印 "type is char *\n"。例如,m_test_type(char *);m_test_type(&amp;s[0]); 都打印 "type is unknown\n"。与sizeof(x) 一样,typeof(x) 是数组x 不会衰减到指针&amp;(x)[0] 的地方之一。
      • 感谢您的评论,这只是复制/粘贴错误,我现在已经修复了
      猜你喜欢
      • 1970-01-01
      • 2020-01-16
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-05
      相关资源
      最近更新 更多