6

我花了很长时间试图弄清楚为什么以下内容无法编译:

enum IPC_RC {OK, EOF, ERROR, NEW };

该错误消息仅说明了它不希望看到一个开放括号的内容。直到我尝试在更现代的编译器上编译它,我才了解到:

/usr/include/stdio.h:201:13: note: expanded from macro 'EOF'
#define EOF     (-1)

所以我终于被一个宏烧死了!:)

我的代码没有#include <stdio.h>(我不包含任何带有 .h 后缀的内容),但显然我包含的某些内容导致包含<stdio.h>. 有什么方法(命名空间?)来保护自己,而不需要准确追踪它包含在哪里?

4

2 回答 2

3

命名空间不是解决方案,因为宏会忽略它们。

所以你有两个选择:

  • 自己摆脱这些宏:

    #ifdef EOF
    #undef EOF
    #endif
    
  • 在枚举值中使用前缀:

    enum IPC_RC
    {
        IPC_OK,
        IPC_EOF,
        IPC_ERROR,
        IPC_NEW
    };
    
于 2013-09-19T12:55:34.513 回答
1

我不知道您描述的问题的令人满意的解决方案,但我只是想分享一种处理这种情况的方法。时不时地(必须)使用一些特别令人讨厌的标题,它重新定义了英语的很大一部分。Python.h想到了X11 标头。我最终做的——而且效果很好——是(通常在我注意到破损之后)我将第 3 方标题包装在我自己的标题中并处理那里的丑陋。

例如,在使用 Ruby 解释器的项目中,我通常不包含ruby.h目录,而是包含一个ourruby.h看起来像这样的文件:

#ifndef RUBY_OURRUBY_H
#define RUBY_OURRUBY_H

// In Ruby 1.9.1, win32.h includes window.h and then redefines some macros
// which causes warnings. We don't care about those (we cannot fix them).
#ifdef _MSC_VER
#  pragma warning(push)
#  pragma warning(disable:4005)
#endif
#include <ruby.h>
#ifdef _MSC_VER
#  pragma warning(pop)
#endif

// In Ruby 1.8.7.330, win32.h defines various macros which break other code
#ifdef read
#  undef read
#endif
#ifdef close
#  undef close
#endif
#ifdef unlink
#  undef unlink
#endif
// ...

#endif // !defined(RUBY_OURRUBY_H)

这样,我就不必记住某些标头并不完全是命名空间干净的事实。

于 2013-07-23T06:39:27.190 回答