如何解决宏和函数之间的名称重复问题? 我用Visual C++ 2008开发。在项目中,我需要包括两个由第三方提供的标题(例如一个是aaa.h,另一个是bbb.h)

如何解决宏和函数之间的名称重复问题? 我用Visual C++ 2008开发。在项目中,我需要包括两个由第三方提供的标题(例如一个是aaa.h,另一个是bbb.h),c++,macros,C++,Macros,不幸的是,在标头aaa.h中有一个名为“Log()”的宏,在标头bbb.h中还有一个名为“Log()”的函数 众所周知,如果源文件中的头aaa.h在bbb.h之前,该函数将在预编译过程中展开,并导致生成错误。现在,我必须将头aaa.h放在每个源文件的bbb.h之后。但是有许多源文件需要包含这两个文件。如果我修改每个文件,它将需要太多的努力 实际上,我只需要在代码中使用宏。这个函数对我的项目没有用处。但是标题属于第三方,我不能修改它 你有更好的方法吗?使用#undef Log,你也可以用不同的名称

不幸的是,在标头aaa.h中有一个名为“Log()”的宏,在标头bbb.h中还有一个名为“Log()”的函数

众所周知,如果源文件中的头
aaa.h
bbb.h
之前,该函数将在预编译过程中展开,并导致生成错误。现在,我必须将头
aaa.h
放在每个源文件的
bbb.h
之后。但是有许多源文件需要包含这两个文件。如果我修改每个文件,它将需要太多的努力

实际上,我只需要在代码中使用宏。这个函数对我的项目没有用处。但是标题属于第三方,我不能修改它


你有更好的方法吗?

使用#undef Log,你也可以用不同的名称从aaa.h复制宏定义,这样你就可以使用它而不会与bbb.h中的函数冲突。

我从来没有遇到过像你描述的那种情况,所以可能有更好的解决方案,但是,也许只要想使用该函数,就可以简单地
#undef

#include "bbb.h"
#include "aaa.h"

// ...

void foo()
{
    // I want to use the macro here
    Log();
}

void bar()
{
    // I want to use the regular function here
    #undef Log

    Log();
}

这就是为什么我们避免使用宏,因为它们没有作用域,这意味着您的选项非常有限

你可以:

  • 重命名宏
  • 重命名函数
  • #取消定义
    在您提到该函数之前,请先删除宏

…就这样。

作为一种解决方法,您可以创建

// bbb_fixed.h

#if defined(Log)
# if defined(__GNUC__) || defined(_MSC_VER) // Maybe other compilers, maybe check version too
#  pragma push_macro("Log") 
#   undef Log
#   include "bbb.h"
#  pragma pop_macro("Log")
# else
#  undef Log
#  include "bbb.h"

// Now restore manually Log macro:
#  define Log // code from #include "aaa.h"

//#  undef AAA_H // aaa.h include guards
//#  #include "aaa.h"

#else // Lod undefined
# include "bbb.h"
#endif
并包括
bbb_fixed.h
而不是
bbb.h

但最好是修复header
aaa.h
以不使用这样的宏。

如果bbb.h中的其他东西不需要Log()函数,请从bbb.h中删除Log()函数

如果文件需要bbb.h,则不需要日志宏: 在bbb.h中添加一个保护字;检查aaa.h中的保护字;如果存在保护字,则取消定义日志宏。(如果需要两个标题,则在aaa.h之前包括bbb.h。)

例如:

bbb.h

aaa.h

如果两者都需要,则可能需要重命名日志宏

编辑:
如果函数重载是可能的,您可以将Log宏修改为Log函数。

在您希望通过名称查找找到函数的地方定义宏如何?

对不起,好奇的是,宏的名称真的是
Log
(在c++的全局范围内)和
aaa.h
作为标题还是仅仅是混淆?这看起来真的很有趣编码标准=)我严重怀疑任何头都不会被称为
aaa.h
;)你听说过名称空间、枚举、静态类成员吗?很抱歉,您必须使用设计糟糕的代码。创建自己的标题
ccc.h
,其中包括
aaa.h
bbb.h
,并按正确的顺序进行排序;在需要
Log()
宏的地方包括
ccc.h
。或者指定一个现有的综合标头来执行此任务。由于宏将有效地覆盖函数,我认为这就是您所需要做的。如果需要在不考虑宏的情况下使用函数,可以
undef
宏,或者将调用括在括号中:
(Log)(…)
调用函数,而不是宏。您可能会在
aaa.h
中遇到阻止宏恢复的标题保护。@LightnessRacesinOrbit:Fixed。这很好:-)(FSVO“很好”)是的,这很有帮助。好主意!谢谢你的评论。这是个好主意,但我不能使用它。原因是我在宏日志中使用宏函数。如果我使用函数调用宏,函数将始终为“foo”。
#include "bbb.h"
#include "aaa.h"

// ...

void foo()
{
    // I want to use the macro here
    Log();
}

void bar()
{
    // I want to use the regular function here
    #undef Log

    Log();
}
#ifndef GUARD_BBB_H
#define Log()  // Log Marco
#endif