g++引入不同目录头文件时误读string.exe致编译错误
搞定g++误把include目录里的可执行文件当输入的坑
先理清楚你遇到的情况
你在Cygwin环境下测试跨目录引头文件时碰了个奇葩问题:
- 测试代码
check.cpp在D:\C++下,里面写了#include <factorial.h>(自己写的头文件)和#include <iostream> - 自制的
factorial.h放在D:\C++\link目录 - 用命令
g++ check.cpp -ID:\C++\link -o done.exe编译,结果:- 只要
link目录里只有factorial.h,编译就正常 - 一旦
link里多了个string.exe,g++就疯了,非要去读这个二进制文件,还报“读取时遇到非法字符”的错误
- 只要
为啥会出这问题?
其实是g的头文件查找规则搞的鬼:
当你用-I指定include目录时,这个目录的优先级比系统默认的标准库目录还高。而你代码里包含了<iostream>,标准库的iostream会间接引用<string>头文件。这时候g会先去你指定的D:\C++\link目录找<string>,结果发现了string.exe——它不管后缀,只要文件名匹配就会尝试读取,二进制文件里的乱码自然就触发编译错误了。
给你几个靠谱的解决办法
按推荐程度排序:
最彻底的:把文件分开放
别把头文件和编译出来的可执行文件堆在同一个目录里!- 专门整个
include目录放所有自制头文件(比如D:\C++\include) - 编译生成的
string.exe这类产物丢去bin目录(比如D:\C++\bin) - 编译命令改成:
g++ check.cpp -ID:\C++\include -o done.exe
从根源上避免文件名冲突,以后也不会再踩类似的坑。
- 专门整个
不想动目录?换个编译参数
用-isystem替代-I,这个参数指定的目录会被当作系统标准库目录,优先级低于默认的系统路径。编译命令改成:g++ check.cpp -isystem D:\C++\link -o done.exe这样g++找
<string>这类标准库头文件时,会先去系统默认目录找,找不到才会去你的link目录,自然就不会碰string.exe了。临时救急:重命名冲突文件
要是赶时间不想改目录或命令,直接把link里的string.exe改个名字,比如my_string.exe,这样g++找<string>时就不会匹配到它了。
验证一下
改完之后再跑编译命令,要是没再报错,还成功生成了done.exe,那问题就解决啦!
内容的提问来源于stack exchange,提问作者Tilak_Chad
相关产品推荐
相关产品推荐

