【问题标题】:how to remove declaration after an include如何在包含后删除声明
【发布时间】:2013-11-22 23:41:22
【问题描述】:

我正在将一个项目迁移到一个新的工具链,并且存在函数名称冲突,来自我的代码和新工具链中包含的函数。我的代码现在必须在新旧工具链中编译,所以我不能随便破解。

例如在同一个包含中,新工具链已经实现了一个 qsort 函数(以及标准库的一部分......所以我不能忽略它),但我有自己的并希望保留一个我有控制权。

有没有办法删除声明(取消声明?)符号,以便使用我项目本地的符号?

我搜索了一段时间,没有找到解决这个问题的策略。

【问题讨论】:

    标签: c


    【解决方案1】:

    通常,工具链不应该重要。编译器永远不会自动为您包含任何内容,因此包含的内容取决于您。这在依赖关系中分崩离析:您#include x.h,新工具链提供了一个x.h,其中还包括y.h,而旧工具链没有。

    一个解决方案是修复你的代码:你真的不应该创建像qsort 这样的函数,它会与标准库函数发生冲突。有什么阻止您将其重命名为 my_qsort 吗?这是一个“好主意”的另一个原因是,如果您的实现与标准库之间存在任何差异,您可能会遇到问题:开发人员对不同行为的混淆是小问题;使用具有不同签名的原型时链接到错误版本的主要问题(即崩溃!)

    另一种解决方案是在仅在一个工具链上需要的标头周围使用#ifdefs,但这可能不适用于x.h,包括y.h 场景。

    【讨论】:

      【解决方案2】:

      C 标准没有提供任何删除声明的方法,而且我还没有听说有任何扩展可以这样做。您的选择包括:

      • 重命名源代码中与标准库标识符冲突的标识符。这是你应该做的。
      • 在包含任何标准头文件之前和之后使用#define#undef 将冲突的名称更改为其他名称。下面是一个例子。这违反了关于保留标识符的标准 C 规则,并且可能会导致问题,具体取决于您使用的 C 实现。
      • 使用#define 更改您的标识符名称。这在技术上也违反了标准 C 规则,但不太可能导致 C 实现出现问题。这需要在每个使用标识符的源文件中完成。示例如下。这里的想法是导致您使用自己的 qsort 标识符(或其他冲突的标识符)的每个实例在预处理器中被另一个不冲突的标识符替换。
      • 您可以修改 C 实现中的头文件。这几乎总是一个坏主意。我提到它只是为了包括所有可能性。 (我不包括的另一种可能性是,因为这是一个更糟糕的想法,您可以修改 C 实现的源代码以提供删除声明的新扩展。)

      这是第二项的示例:

      #define qsort StandardLibraryQsortRenamedDueToConflict
      #include <stdlib.h>
      #undef qsort
      

      这里是第三项的例子:

      #include <stdlib.h>
      #define qsort MyQsort
      #include "MyHeader.h"
      

      如果您在自己的头文件之一之后包含标准头文件,并且无法对其重新排序,则必须使用#undef 以避免干扰标准头文件:

      #define qsort MyQsort
      #include "MyHeader0.h"
      #undef qsort
      #include <stdlib.h>
      #define qsort MyQsort
      #include "MyHeader1.h"
      

      如果在任何源文件中的任何麻烦的头文件之后都没有包含标准头文件,那么,您可以简单地将每个#define 放在其相应的头文件中,而不是在每个源文件中插入上述头文件。所以MyHeader.h 可能看起来像:

      … // Various code.
      #define qsort MyQsort
      void qsort(parameter…)
      

      【讨论】:

        【解决方案3】:

        这是一个很常见的问题,不幸的是它依赖于库代码的作者来使用唯一的名称。 win32 windows API 标头在这方面是出了名的糟糕。

        没有办法“取消声明”符号,但如果您使用的是 c++,那么您始终可以将代码放在命名空间中以避免冲突。

        当然,另一种选择是简单地重命名您的函数或将其添加到 DLL/SO 并以不同的名称公开可见函数。

        【讨论】:

        • 对不起,我刚开始使用堆栈溢出,看不到指定语言的位置。
        • 没问题。这些标签一开始很容易错过。
        猜你喜欢
        • 2011-07-27
        • 2020-06-16
        • 2017-10-14
        • 2016-06-18
        • 1970-01-01
        • 2020-01-08
        • 2016-10-17
        • 1970-01-01
        相关资源
        最近更新 更多