包含的 cpp 库上的宏正在破坏代码库的其余部分

Posted

技术标签:

【中文标题】包含的 cpp 库上的宏正在破坏代码库的其余部分【英文标题】:Macro on cpp library included is ruining the rest of the codebase 【发布时间】:2020-09-23 06:49:51 【问题描述】:

我正在开发一个包含这个库的应用程序,我们称之为 Snap.h。

我发现如果 Snap.h 不是包含语句的最后一个,编译会失败。仔细一看,我发现这段代码在 Snap.h 包含的头文件中

#define Try try 
#define Catch  catch (PExcept Except)ErrNotify(Except->GetMsgStr());
#define CatchFull  catch (PExcept Except)ErrNotify(Except->GetStr());
#define CatchAll  catch (...)

基本上这可以让 try 和 catch 块用作语句,就像这样

Try;
<some code>
Catch;

您可以看到这是一个问题,这些通用宏很容易与其他库发生冲突。

不幸的是,这是数万行非常复杂的代码,而我正在开发的应用程序是围绕这个库构建的。它不容易改变。

Cpp 不是我的强项,有没有办法限制宏在包含中的影响?

【问题讨论】:

here a way to limit the effects of macros in an include?#undef? 将它放在包含列表的最后是第一个选项。您还可以引入另一个标头并将其放在标头的末尾,并使用 #undef 所有这些宏,这样您的代码将受到保护以降低宏的可见性 #include "snap.h" #include "stap_undef.h"跨度> 你根本不需要在你自己的代码中使用这种风格,我们希望它总是在Snap 东西中正确和一致地使用。 这样的宏技术是恕我直言的反模式(可能会导致您遇到的问题)。在标头中查找此类内容会使代码对我非常可疑。有机会把这些东西扔掉吗?我知道 trycatch 在 C++ 程序中做什么,但 Try;Catch;?我以前从未见过这样的事情。有更好的方法来自动化try/catch,例如将其包装在一个函数中,其中内部块(@​​987654331@ 和 catch 之间)作为参数提供 - 例如std::function 或者更聪明的东西。 我认为在包含 Snap.h 的任何时候都包含 #undef 头文件会起作用。 更好的是:编写一个新的头文件 fixedSnap.h#include&lt;snap.h&gt; 和然后是所有必要的#undefs,然后在其余代码中仅使用#include "fixedSnap.h"。 ;-) 【参考方案1】:

我不太喜欢 #undef 的东西,因为你现在永远不会有什么其他坏东西可以沉睡在那个大标题中。我更喜欢将其隔离在“编译屏障”中,即仅将其包含在单独的包装翻译单元中,该翻译单元仅重新定义和转发您需要的内容。在以下示例中,Snap.hBULLSHIT 重新定义为 std::terminate,但您可以尝试,main.cpp 可以在没有 Snap.h 版本的情况下使用 Snap.h 中的函数@:

/*! @file main.cpp
 */
#include <iostream>

#define BULLSHIT
#include "snap_wrapper.h"

int main() 
    BULLSHIT
    std::cout << wrapper::nice_function() << "\n";



/*! @file Snap.h
 */
#ifndef UNTITLED5_SNAP_H
#define UNTITLED5_SNAP_H

#define BULLSHIT std::terminate();

int nice_function() 
    return 42;


#endif //UNTITLED5_SNAP_H

/*! @snap_wrapper.h
 */

#ifndef UNTITLED5_SNAP_WRAPPER_H
#define UNTITLED5_SNAP_WRAPPER_H

namespace wrapper
int nice_function();


#endif //UNTITLED5_SNAP_WRAPPER_H

/*! @file snap_wrapper.c
 */

#include "snap_wrapper.h"
#include "Snap.h"

namespace wrapper 

        int nice_function() 
            return ::nice_function();
        


【讨论】:

以上是关于包含的 cpp 库上的宏正在破坏代码库的其余部分的主要内容,如果未能解决你的问题,请参考以下文章

在预编译项目/库的其余部分时动态编译App_Code中的类

C# 无法在未损坏的 C++ 库上找到入口点

编辑单个 YAML 值而不更新 YAML 其余部分的格式(YAML CPP)[重复]

g ++用户定义的动态链接库上的全局new和delete运算符

在远程存储库上提交历史记录

链接 Yaml-cpp 和 Armadillo 共享库的 CMake 项目