命名空间和定义之间的冲突
我有这个严重的问题。我在 2 个命名空间内有一个枚举,如下所示:
namespace FANLib {
namespace ERROR {
enum TYPE {
/// FSL error codes
FSL_PARSER_FILE_IERROR,...
在我的代码中的其他地方,我像这样使用它:
FANLib::Log::internalLog(FSLParser::FILE_IERROR, file_ierror, true, FANLib::ERROR::FSL_PARSER_FILE_IERROR);
所有编译都很好,但如果我碰巧包含“windows.h”,我会收到错误!问题出在“WinGDI.h”中,其中包含以下行:
#define ERROR 0
并使编译器认为在 FANLib::... 之后有一个零! 我得到的错误是:
错误 1 错误 C2589:“constant”:“::”右侧的非法标记
错误 2 错误 C2059:语法错误:'::'
错误 3 错误 C2039:“FSL_PARSER_FILE_IERROR”:不是“全局命名空间”的成员
我能对此做些什么,而不必因为一些轻率的 #define
而更改我的命名空间吗?我在另一篇文章中读到我可以 #undef 错误,但这有多安全?
I have this serious problem. I have an enumeration within 2 namespaces like this:
namespace FANLib {
namespace ERROR {
enum TYPE {
/// FSL error codes
FSL_PARSER_FILE_IERROR,...
and somewhere else in my code, I use it like this:
FANLib::Log::internalLog(FSLParser::FILE_IERROR, file_ierror, true, FANLib::ERROR::FSL_PARSER_FILE_IERROR);
All compiles fine and well, but if I happen to include "windows.h", I get errors! The problem is in "WinGDI.h" which has this line:
#define ERROR 0
and makes the compiler think that, after FANLib::..., there is a zero!
The error I get is :
Error 1 error C2589: 'constant' : illegal token on right side of '::'
Error 2 error C2059: syntax error : '::'
Error 3 error C2039: 'FSL_PARSER_FILE_IERROR' : is not a member of '`global namespace''
Is there anything I can do about this, without having to change my namespaces due to some thoughtless #define
? I have read in another post that I could #undef ERROR, but how safe is that?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一般来说,您应该避免使用全大写标识符,因为它们用于宏。在这种情况下,我将重命名命名空间。
(顺便说一句,
#define
等其他东西,例如GetPrinter
,实际上它很烦人。我通常会选择#undef
然后,仅在 .cpp 文件中包含
并确保受标头影响的范围尽可能小。)Generally, you should avoid using all-caps identifiers as they are used for macros. In this case, I'd rename the namespace.
(As a side note,
<windows.h>
#define
s other stuff likeGetPrinter
and indeed it gets annoying. I usually go with#undef
then. It also helps to only include<windows.h>
in .cpp files and make sure the scope affected by the header is as small as possible.)重命名命名空间是最干净、最安全、最具互操作性的解决方案。
Renaming your namespace is the cleanest, safest, most interoperable solution.
跳上“重命名你的命名空间”的潮流,只是因为
ERROR
这个名字太常见和模糊了。寻找更具描述性的内容。Hopping on the "rename your namespace" bandwagon, simply because
ERROR
is way too common and vague a name. Find something more descriptive.我认为如果你 #undef 它不会有问题。但是,您必须在使用枚举和枚举的任何地方执行此操作。 windows.h。最好的事情是重命名您的名称空间。
I think it won't be a problem if you #undef it. But, you would have to do it everywhere you use both your enum & windows.h. The best thing would be renaming your namespace.
您可能需要重构代码,以便 #include 仅在必要时出现。 “正确”的方法甚至可能涉及制作单独的文件和标头,其中包括您将从 windows.h 调用的函数的接口。
但是,如果您只想要一个简单的修复并担心 #undef ERROR 的副作用,只需重新定义 ERROR完成声明后:
每次提到错误(而不是在字符串中)时,您都必须执行此操作。
话虽如此,如果你只是未定义的错误,你应该没问题。它只会影响 C 预处理器从该点开始处理 ERROR 的方式(或者更确切地说不影响它的处理方式)。
顺便说一句,我通常看到全大写字母的名称仅用于指定常量,而不用于指定类型和命名空间。如果我是你,我会重新考虑我的命名约定..
You might want to refactor your code so that that #include only appears where necessary. The "correct" way might even involve making separate files and headers that include interfaces to the functions you will call from windows.h
However, if you just want a simple fix and are concerned about side-effects from #undef ERROR, just redefine ERROR after you are finished with your declaration:
You would have to do this everytime ERROR is referred to (and not in a string).
Having said that, you should be ok if you simply just undefined ERROR. It would only affect how the C preprocessor handles ERROR (or rather how it does not) from that point onwards.
By the way, I've generally seen names in all capital letters only be used to specify constants, not for types and namespaces. I'd reconsider my naming convention if I were you ..
最好的解决方案是更改命名方案以避免全部大写,正如其他人建议的那样:
也禁止使用:以 _ 或 __ 开头的标识符。 (情况比这更复杂,但是如果您避免所有以下划线开头的名称,您的生活会更简单。)
The best solution is to change your naming scheme to avoid all-caps, as others have suggested:
Also off limits: identifiers that start with _ or __. (It's more complicated than that, but your life will be simpler if you just avoid all names that start with an underscore.)
如果您不使用 GDI,那么您可以定义
NOGDI
来禁止在 WinGDI.h 中定义宏。 在这里您可以找到其他有用的选项。If you do not use GDI then you could define
NOGDI
to suppress defining macros in WinGDI.h. Here you could find other useful options.以 E 和数字或 E 和大写字母开头的标识符应被视为保留,因为这样的新宏可以添加到
中。Identifiers that begin with E and a digit or E and an uppercase letter should be treated as reserved, as such new macros could be added to
<errno.h>
.