【问题标题】:C macro get typeof argumentC 宏获取 typeof 参数
【发布时间】:2013-02-26 10:33:15
【问题描述】:

我正在尝试编写一个宏来协助在 C 中进行面向对象编程。由于我将类信息存储在一个常量结构中,因此我需要创建一个执行以下操作的宏:

  • 获取对象的类型(解除引用的指针的类型)
  • 附加 _info 以获取所需 classInfo 结构的名称
  • 获取该符号的地址,以便将其传递给函数
  • 使用指向类结构和对象本身的指针调用 destroyObject 函数

一个例子:

queue_t* p = NULL;
delete(p);

delete 应扩展为:

destroyObject(&(queue_t_info), p);

我尝试使用此宏,但无法开始工作:

#define delete(X) (destroyObject(&(typeof(*X)##_info), X))

我在 typeof 部分无法正常工作时遇到问题。

【问题讨论】:

  • 你似乎认为类型有名字。
  • 所以当传递一个整数的引用时,根本不可能让 preprossor 吐出int
  • @melpomene 为什么你认为他们没有?
  • 实际上,考虑到这一点,我意识到预处理器尚未解析我的代码,因此它无法将变量与类型相关联。我想出了一个不错的解决方案来解决这个问题。我会把它作为问题的答案发布。
  • 当编程试图将语言(这里的 C)变成(某种)它不是的东西(OO,这里)时,你能做的最糟糕的事情。它只会让你的读者(可能在几周后你自己)感到非常困惑,甚至会欺骗编译器变得愚蠢/生成错误的代码。想要类似 C 的 OOP?选择 C++。

标签: c macros c-preprocessor


【解决方案1】:

typeof 不是宏,它是语言构造,它由编译器扩展,而不是预处理器。由于预处理在编译之前进行,因此宏无法访问typeof 结果。

您的delete(p) 扩展为:(destroyObject(&(typeof(*p)_info), p))。 (可以通过-Egcc flag 看到)

【讨论】:

    【解决方案2】:

    我意识到我试图做的事情是不可能的 - C 预处理器不会解析和符号化代码,因此它不知道变量是哪种类型。

    为了解决这个问题,我还需要将类型传递给删除函数。这并不理想,因为它引入了由于类型不匹配而导致的常见错误来源。如果程序员传递了一个指向对象 A 的指针,但在删除函数中指定了对象 B,则会调用错误的析构函数。为了解决这个问题,我在宏中添加了类型检查,以便为任何不匹配的类型生成编译器警告。

    #define typecheck(type,x) \
    ({  type __dummy; \
    typeof(x) __dummy2; \
    (void)(&__dummy == &__dummy2); \
    })
    
    #define delete(P, X) (destroyObject(&(X##_info), P), typecheck(X, *P))
    #define new(X, ...) (createObject(&(X##_info), ##__VA_ARGS__))
    

    宏的正常使用:

    queue_t* p = new(queue_t);
    delete(p, queue_t);
    

    但是使用了错误的类型:

    queue_t* p = new(queue_t);
    delete(p, int);
    

    导致编译器警告:

    Comparison of distinct pointer types ('int *' and 'typeof (*p) *' (aka 'queue_t *'))
    

    【讨论】:

      猜你喜欢
      • 2018-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      相关资源
      最近更新 更多