在项目中只调用一次宏

Posted

技术标签:

【中文标题】在项目中只调用一次宏【英文标题】:Calling a macro only once in the project 【发布时间】:2017-08-18 08:02:40 【问题描述】:

我正在尝试在项目中设置easylogging++,但遇到以下问题:

INITIALIZE_EASYLOGGINGPP 在项目中只能调用一次。现在,如果我从我的main.cpp 调用这个宏并且只在main.cpp 中包含easylogging++.h - 一切正常。但是,当我尝试将easylogging++.h 包含在更多.cpp 文件中时,我会遇到未定义引用的链接器问题(好像尚未调用宏)。 如果我将对该宏的调用放在按字母顺序排列在main.cpp 之前的文件中,则链接器会正常解析所有内容。在链接阶段,对象按字母顺序排序。

有没有解决这个问题的好方法?还是我必须尝试在链接时强制使用不同的文件顺序?

我对这类问题没有太多经验,尝试谷歌搜索,找不到解决方案。如果已经有类似的问题,抱歉,没找到。

感谢您的帮助!

【问题讨论】:

预处理器宏和链接器错误很少关联。请尝试创建Minimal, Complete, and Verifiable Example 并向我们展示,以及向我们展示您遇到的实际错误(以文本形式复制粘贴,完整、完整且未经任何修改)。 关于术语的注释,预处理器宏不是“调用”而是扩展。简而言之,在 C++ 解析器读取源代码之前,宏调用在源代码中被宏的扩展主体替换 您好,感谢您的评论,这不是一个小项目,所以我稍后会尝试创建一个最小的示例并将输出复制到这里。 【参考方案1】:

也许您可以将调用包装在使用std::call_once() 调用的函数中,例如:

void setup_logging() 
  static std::once_flag once;
  std::call_once(once, [] ()  INITIALIZE_EASYLOGGINGPP(); );

这样您可以多次调用setup_logging(),但宏会被调用一次。

【讨论】:

【参考方案2】:
#ifndef INITIALIZE_EASYLOGGINGPP
#define INITIALIZE_EASYLOGGINGPP SomeLogic
#endif

#ifndef 将检查令牌是否已被定义,在这种情况下,此部分将被忽略。

【讨论】:

【参考方案3】:

有些程序员是对的,链接+宏没有问题。

在尝试重新创建将其发布到此处的最小示例后,我意识到 CMakeLists.txt 中有一个错误导致 main.cpp(我在其中扩展了 easylogging++ 宏)在某些情况下被排除在构建之外.

感谢大家的宝贵时间,并对愚蠢的问题表示歉意。

【讨论】:

以上是关于在项目中只调用一次宏的主要内容,如果未能解决你的问题,请参考以下文章

快速排序变种实现:一次宏定义引发的熬夜事件

API 调用在循环中只返回一次响应

cellForItemAt 在 Swift collectionView 中只调用一次

在 Pig 中只执行一次 UDF

从一个类中只调用一次方法

有没有办法在反应功能组件中只进行一次 api 调用?