Macros C++;声明的常量与定义的常量同名

Macros C++;声明的常量与定义的常量同名,macros,autoconf,automake,Macros,Autoconf,Automake,是否有一种标准或好的方法可以避免声明的常量与定义的常量命名相同 我的问题 我试图在linux中使用autoconf编译我的程序,它定义了版本,但在Mongo的一个db头文件中,它们声明了一个常量命名的版本。使用右边的值命名变量显然有问题 通常我只会更改名称,但在这种情况下,它不是我的库。我可以想出如何重命名已定义的变量autoconf 有什么建议吗?您必须在configure.ac文件中使用no define和AM\u INIT\u AUTOMAKE 默认情况下,此宏定义的包和版本。这可能是 通

是否有一种标准或好的方法可以避免声明的常量与定义的常量命名相同

我的问题

我试图在linux中使用autoconf编译我的程序,它定义了版本,但在Mongo的一个db头文件中,它们声明了一个常量命名的版本。使用右边的值命名变量显然有问题

通常我只会更改名称,但在这种情况下,它不是我的库。我可以想出如何重命名已定义的变量autoconf


有什么建议吗?

您必须在
configure.ac
文件中使用
no define
AM\u INIT\u AUTOMAKE

默认情况下,此宏定义的包和版本。这可能是 通过传递no define选项来避免,如:

AM_INIT_AUTOMAKE([gnits 1.5无定义dist-bzip2])


请参阅。

如果已将错误本地化,可以执行以下操作:

const unsigned int OLD_VERSION = VERSION;
#undef VERSION
#include <mongodb_header.h>
const unsigned int OLD_VERSION=VERSION;
#未定义版本
#包括
然后在代码中使用
OLD_VERSION
,而不是
VERSION
。或者在另一个名称空间中定义您的版本


另外,在Mongodb中提交一个bug。在外部命名空间中仅使用
VERSION
作为名称是不正确的。它至少应该检查
VERSION
是否已经定义,或者是否在变量前面加上前缀,例如
MONGODB\u VERSION
,或者类似的东西。

一般来说,没有好的方法来保护自己不受某些第三方库可能污染全局命名空间的影响。这就是上帝发明名称空间的原因

如果版本是编译时已知的全局符号,则可以使用名称空间:

namespace yourStuff
{
    int VERSION;

    // references to VERSION here refer to the inner VERSION, not ::VERSION
}
但如果VERSION是一个预处理器宏(我怀疑它是大写的),那么它就不遵循任何编译规则,并且存在于编译器规则之外。您可以使用其他预处理器宏检测它:

#ifdef VERSION
 // define it to be something else
#else
#endif
(或者像迭戈的回答中那样使用#undef来杀死它)


但在任何地方这样做都会让人讨厌。您只需要不使用VERSION。

这不是一个很好的建议,但根据库的大小,您可以浏览所有文件,并使用“查找和替换”工具手动将对VERSION的所有引用替换为名称更合适的变量。显然,对于较大的库来说,这是不合适的。您是在问有关该语言的问题,还是仅仅是关于如何避免autoconf的情况?Doug,主要是在autoconf中避免这种情况。我正在将代码库切换到autoconf,这是我遇到的一个错误。艾略特,是的,我可以。这就是我确认问题的方式,但当我想要升级mongo的lib时,这会导致问题,等等。请参阅我的答案,以了解解决OP问题的正确方法。除此之外,我建议不要使用
#undef
,更喜欢
#pragma push_宏(“macro_name”)
#pragma pop_宏(“macro_name”)
,如果编译器支持的话。Mmm。。。这有一些缺点。如果他或她真的想要程序中的变量版本呢?将
no define
添加到
AM\u INIT…
不会添加变量。他或她可以手动添加它,但我认为这里要解决的问题是编写糟糕的
.h
文件(以任何方式)污染了外部名称空间。至于push和pop宏,它们很好。我不知道它们,但我想知道它们的可移植性……迭戈,我不认为mongo污染了外部名称空间。问题是它们使用的是一个公共定义的常量。他们将其包装在mongo名称空间中。非常感谢,automake是否将该版本用于任何用途,还是仅用于用户代码库。如果是这样的话,我可以使用AC_DEFINE(PROG_版本,“5.6”)将其定义为其他内容。我认为这些定义仍然存在,因为遗留的原因。我可能错了,但例如,在创建包时,deb工具使用的是afaik
PACKAGE\u NAME
PACKAGE\u VERSION