【问题标题】:Parameterless function in #define macro causes error despite gcc -E output being correct#define 宏中的无参数函数会导致错误,尽管 gcc -E 输出正确
【发布时间】:2015-05-30 10:46:43
【问题描述】:

我有一个对象来存储系统范围的颜色属性,其中包含大量重复代码,例如:

Q_PROPERTY( QColor backgroundColor MEMBER m_backgroundColor NOTIFY backgroundColorChanged )

接着是:

QColor m_backgroundColor;
signals: void backgroundColorChanged();

我现在有数百个,对象很难读取和修改,所以想用宏替换上面的,例如:

#define COLOR(name) public: Q_PROPERTY( QColor name MEMBER m_##name NOTIFY name##Changed ) signals: void name##Changed(); private: QColor m_##name;

紧随其后

COLOR(backgroundColor)

如果我在这个文件上运行 gcc -E 它会给出我期望的输出:

public: Q_PROPERTY( QColor backgroundColor MEMBER m_backgroundColor NOTIFY backgroundColorChanged ) signals: void backgroundColorChanged(); private: QColor m_backgroundColor;

但是当我尝试构建项目时,它给了我以下错误:错误:属性'backgroundColor'的通知信号'backgroundColorChanged'在类Colors中不存在。

但是,如果我手动复制 gcc -E 的输出并将其粘贴到头文件中,它将编译并运行没有问题。

为什么正确扩展的宏无法像这样构建,我该如何解决?

【问题讨论】:

  • 您的问题是 COLOR 扩展为宏,但该宏没有扩展,预处理器继续运行。所以你所拥有的基本上是需要再通过一次预处理器的代码
  • 但是,如果我从 COLOR 宏中删除 signals: void name##Changed();,它会编译并运行,尽管没有更改信号。这似乎是导致问题的();
  • 请注意,错误是由moc 给出的,而不是由 GCC 给出的。也许是错误/限制?

标签: c++ qt gcc clang c-preprocessor


【解决方案1】:

恐怕这个问题没有解决办法。

Moc 解析 C++ 头文件中的信号和属性。它不会扩展任何宏,因此看不到您的信号。你可以看到产生这个错误的代码here,没有办法禁用或欺骗这个检查。

理想情况下,这应该在 moc 中修复(它应该提供绕过此检查的选项,或者能够像编译器那样扩展宏)。在将标头传递给 moc 之前,您可以使用另一个预处理器将宏扩展为另一个文件(如果您使用 cmake,这是完全可能的,但我不确定 qmake),但我认为这是矫枉过正。我建议您从宏中删除信号声明并明确定义信号。

【讨论】:

  • 谢谢,这似乎是问题所在。手动定义信号是可行的,而且解决方法也不错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-28
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多