G ++似乎忽略了#ifdef的#include

Posted

技术标签:

【中文标题】G ++似乎忽略了#ifdef的#include【英文标题】:G++ seems to be ignoring #ifdef for an #include 【发布时间】:2016-05-23 13:43:30 【问题描述】:

环境 Ubuntu 16.04 G++ 5.3.1

我有一个包含以下内容的头文件,旨在根据平台包含不同的 .h 文件:

#ifdef _WIN32 
#include "curses.h"
#else
#include <ncurses.h>
#endif

这在 Windows 中运行良好,但在 Ubuntu 中我收到有关 curses.h 文件的错误:

In file included from /usr/include/unctrl.h:54:0,
                 from /usr/include/curses.h:1694,
                 from headers/command_window.h:8,
                 from command_window.cpp:1:
headers/curses.h:900:19: error: macro "clear" passed 1 arguments, but takes just 0
int     clear(void);

编译时使用:

g++  -g -lncurses -std=c++11  -Iheaders  -c -o command_window.o command_window.cpp

为什么要在此处涉及用于 PDCurses 的 windows 特定文件 headers/curses.h?

【问题讨论】:

使用this old answer 了解如何转储所有预定义的宏。您也可以在预处理后停下来查看编译器看到的源代码。 _WIN32 似乎不在使用旧答案的定义列表中 【参考方案1】:

/usr/include/unctrl.h 包含这一行:

#include &lt;curses.h&gt;

由于您已告诉编译器在您的 headers/ 文件夹中查找带有 -Iheaders 标志的头文件,因此编译器会在该文件夹中选择 curses.h

因此您需要删除-Iheaders 标志(例如使用#include "headers/header_name.h")或者您需要重命名headers/curses.h 以免与/usr/include/curses.h 发生冲突

【讨论】:

这似乎有点不对劲,您的假设是它使用了系统包含语法,但-I 选项不会影响系统标头的搜索路径。特别是,您在-I- 选项之前使用-I 选项指定的任何目录都只会搜索#include "file" 的情况;他们不会搜索#include &lt;file&gt; 嗯,找到了正确版本的 g++ 文档,看起来这是故意破坏的:*请在 -I 目录中使用 -iquote 而不是 -I- 之前的目录,并删除 -I-选项。您在-I- 选项之前使用-I 选项指定的任何目录仅搜索#include "file" 的情况;他们不会搜索#include &lt;file&gt;。如果在-I- 选项之后使用-I 选项指定了其他目录,则会在这些目录中搜索所有#include 指令。 (通常所有-I 目录都是这样使用的。) * @BenVoigt 此处的文档gcc.gnu.org/onlinedocs/cpp/Search-Path.html 指出,使用-I 添加的目录在&lt;brackets&gt; 中包含的#include 文件的任何默认目录(例如/usr/include)之前搜索 -这符合我的经验。 "header"&lt;header&gt; 与 gcc 的主要区别在于“标题”首先相对于文件,而 -I.-I- 具有特殊含义。 有两个因素:顺序,以及#include中是否使用""&lt;&gt;来命名文件。 @BenVoigt 使用-I 添加的目录使gcc 在""&lt;&gt; 情况下搜索任何系统目录(例如/usr/include/)之前的目录。【参考方案2】:

在您的 g++ 版本中,-I 选项不是向搜索路径添加特定于应用程序的头文件(#include 不应在系统头文件中找到的那些)到搜索路径的正确方法(此更改令人惊讶我也是)。

您应该使用-iquote headers

看到这个答案:How to tell g++ compiler where to search for include files? 和这个official documentation

【讨论】:

以上是关于G ++似乎忽略了#ifdef的#include的主要内容,如果未能解决你的问题,请参考以下文章

似乎它忽略了 apollo graphql 中的更新突变?

自定义的 UITableViewCell 约束似乎被忽略了

NLog LogException 似乎忽略了异常

@RefreshScope 似乎忽略了 Mockito 的嘲笑

QWidget 似乎忽略了 EventFilter 传递的事件

Delphi 似乎忽略了我的一些代码行?