如何在包含后删除声明

时间:2013-11-22 23:41:22

标签: c

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

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

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

我已经搜索了一段时间,但没有找到解决此问题的任何策略。

3 个答案:

答案 0 :(得分:2)

通常情况下,工具链不应该重要。编译器永远不会自动包含任何内容,因此包含的内容取决于您。分崩离析的地方依赖于:您#include x.h,而新工具链提供的x.h也包含y.h,其中旧版本没有。{/ p>

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

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

答案 1 :(得分:1)

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…)

答案 2 :(得分:0)

这是一个非常常见的问题,遗憾的是它依赖于库代码的作者来使用唯一的名称。 win32 windows API标头在这个领域非常糟糕。

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

另一个选择当然是简单地重命名你的函数或将它添加到DLL / SO并公开一个具有不同名称的可见函数。