ifstream的头文件(头文件中的ifndef)

ifstream的头文件(头文件中的ifndef)p u C 语言 u 中的 include 很简单 但不是你想象中的简单 p 之前写过一个 C 语言的 include 没你想的那么简单 广受大家喜爱 详见 C 语言的 include 没你想的那么简单 图文版 或 C 语言的 Include 没你想的那么简单 u 视频 u 版 p p 最近又遇到个新问题

大家好,我是讯享网,很高兴认识大家。



 <p> <u>C语言</u>中的include很简单,但不是你想象中的简单。</p> 

讯享网

讯享网之前写过一个《C语言的include没你想的那么简单》,广受大家喜爱,详见《C语言的include没你想的那么简单(图文版)》或《C语言的Include没你想的那么简单(<u>视频</u>版)》。</p> 

最近又遇到个新问题,对于同名头文件,编译器是怎么处理的?</p> 

讯享网我这个踩坑过程就不细说了,说多了都是泪,直接上干货吧!</p> 

<strong>如果你嫌我啰嗦,你就直接拖到文末看截图的结果汇总吧!</strong></p> 

讯享网为了讲清楚这个问题,我做了个实验,编了个这样的目录结构和文件:</p> 

</p> 

讯享网 https://www.elecfans.com/d/ │ main.c │ ├─inc1 │ inc.h │ inc1.c │ └─inc2 
 inc.h</pre> 
而这些文件内容分别如下: (1)https://www.elecfans.com/d/main.c
讯享网 // https://www.elecfans.com/d/main.c #include 
  
    
  
   
     
    #include “inc.h” 
   
     
    
   
     
   extern int inc1(void); 
   
     
   int main(void) { 
   
     
   
讯享网
printf("main VAL=%d 
”,VAL);
讯享网printf("inc1 VAL=%d 
”,inc1());
return 0; 
}
(2)https://www.elecfans.com/d/inc1/inc.h
讯享网 // https://www.elecfans.com/d/inc1/inc.h #ifndef _INCH #define _INCH #pragma message(FILE) #define VAL 1 #endif
(3)https://www.elecfans.com/d/inc1/inc1.c
 // https://www.elecfans.com/d/inc1/inc1.c #include “inc.h” int inc1(void) { 
讯享网return VAL; 
}
(4)https://www.elecfans.com/d/inc2/inc.h
 //https://www.elecfans.com/d/inc2/inc.h #ifndef _INCH #define _INCH #pragma message(FILE) #define VAL 2 #endif
然后,我分别用Cygwin上的GCC、Linux上的GCC、Window上的GreenHills和Windows上的ARMCC做了测试。 首先,直接在Windows上的命令窗口上直接执行(基于Cygwin上的GCC):
讯享网 gcc .main.c.inc1inc1.c-omain
得到的是
 .main.c:2:10: fatal error: inc.h: No such file or directory 
讯享网2 | #include "inc.h" | ^~~~~~~ 
compilation terminated. .inc1inc1.c:1:10: fatal error: inc.h: No such file or directory
1 | #include "inc.h" | ^~~~~~~ 
compilation terminated.

你会发现有两个错误,.main.c里面的inc.h找不到还好理解,但是.inc1inc1.c里面的inc.h也找不到?跟inc1.c同级的目录下有一个inc.h啊?!
接下来,通过编译选项-I(指定头文件路径)加入头文件路径看看。
讯享网 gcc .main.c .inc1inc1.c -Iinc1 -Iinc2 -o main
得到的是
 In file included from .main.c:2: inc1/inc.h:3:11: note: ‘#pragma message: inc1/inc.h’ 
讯享网3 | #pragma message(__FILE__) | ^~~~~~~ 
In file included from .inc1inc1.c:1: inc1/inc.h:3:11: note: ‘#pragma message: inc1/inc.h’
3 | #pragma message(__FILE__) | ^~~~~~~</pre> 

两个地方认的都是inc1/inc.h。可以理解,-Iinc1 -Iinc2哪个先就用哪个。
接着,只指定-Iinc2,看看什么效果
讯享网 gcc .main.c .inc1inc1.c -Iinc2 -o main
得到的是
 Infileincludedfrom.main.c:2: inc2/inc.h:3:11: note: ‘#pragma message: inc2/inc.h’ 3 | #pragma message(FILE) | ^~~~~~~ In file included from .inc1inc1.c:1: inc2/inc.h:3:11: note: ‘#pragma message: inc2/inc.h’ 3 | #pragma message(FILE) |^~~~~~~

好家伙,两个地方都认的是inc2/inc.h!.inc1inc1.c为什么不要它旁边的inc1/inc.h呢?

难道通过-I指定路径的优先级是最高的?接下来,通过-I指定一个空路径试试。
讯享网 gcc.main.c.inc1inc1.c-I-Iinc1-Iinc2-o main
</p> 
讯享网得到的是</p> 
</p> 
讯享网 In file included from .main.c:2: inc2/inc.h:3:11: note: ‘#pragma message: inc2/inc.h’ 3 | #pragma message(FILE) | ^~~~~~~ In file included from .inc1inc1.c:1: inc2/inc.h:3:11: note: ‘#pragma message: inc2/inc.h’ 3 | #pragma message(FILE) | ^~~~~~~

看清楚这里哦-I-Iinc1-Iinc2,按刚才的推测,-I的优先级是最高的,但是这个-I是什么路径?导致最终用的头文件是inc2/inc.h??

不行,再来一发,将-I改为-Ihttps://www.elecfans.com/d/,这样又会怎样呢?
 gcc .main.c .inc1inc1.c -Ihttps://www.elecfans.com/d/ -Iinc1 -Iinc2 -o main
讯享网</p> 
‍</p> 
讯享网得到的是</p> 
 Infileincludedfrom.main.c:2: inc1/inc.h:3:11: note: ‘#pragma message: inc1/inc.h’ 
讯享网3 | #pragma message(__FILE__) | ^~~~~~~ 
In file included from .inc1inc1.c:1: inc1/inc.h:3:11: note: ‘#pragma message: inc1/inc.h’
3 | #pragma message(__FILE__) | ^~~~~~~</pre> 
凌乱了吧,-I和-Ihttps://www.elecfans.com/d/是不一样的?!
讯享网</p> 
 等等,是不是Windows这“/”和“”不一样,Powe<u>rs</u>hell和Cygwin杂交就不一样了?? 于是,我找了个纯血的Linux+GCC试试。把路径中的换成/:</p> 
讯享网 gcc https://www.elecfans.com/d/main.chttps://www.elecfans.com/d/inc1/inc1.c-omain
</p> 
讯享网</p> 
 https://www.elecfans.com/d/main.c:2 fatal error: inc.h: No such file or directory 2 | #include “inc.h” | ^~~~~~~ compilation terminated. In file included from https://www.elecfans.com/d/inc1/inc1.c https://www.elecfans.com/d/inc1/inc.h:3 note: ‘#pragma message: https://www.elecfans.com/d/inc1/inc.h’ 3 | #pragma message(FILE) | ^~~~~

果真,对比上面第一个案例,这里只提示一个错误,说明如果不用-I指定头文件,编译器是可以就近找到当前路径的头文件的。
接下来,再看一个例子
讯享网 gcc https://www.elecfans.com/d/main.chttps://www.elecfans.com/d/inc1/inc1.c-Iinc2-omain
 In file included from https://www.elecfans.com/d/main.c:2: inc2/inc.h:3:11: note: ‘#pragma message: inc2/inc.h’ 3 | #pragma message(FILE) | ^~~~~ In file included from https://www.elecfans.com/d/inc1/inc1.c:1: https://www.elecfans.com/d/inc1/inc.h:3:11: note: ‘#pragma message: https://www.elecfans.com/d/inc1/inc.h’ 3 | #pragma message(FILE) | ^~~~~~~

这里说明,并不是-Iinc2指定的优先级是最高的,https://www.elecfans.com/d/inc1/inc1.c还是能找到最近的头文件https://www.elecfans.com/d/inc1/inc.h。

这说明什么呢?不知道,不好说,反正我就不相信网上说的那些,我只相信实验出来的结果。

小平同志说过:实践是检验真理的唯一标准!

那么,我就用我电脑上的其他几个编译器(Greenhills里的CCRH850、S32DS里的ARMCC),全部搞一遍,做个对比。我用红框把异类标出来了: b45dae76-90b5-11ef-a511-92fbcf53809c.png

然后,有什么规律呢,自己总结哈!我是不记这些的,写几个代码试试就知道结果了。
讯享网</p> 
</p> 
小讯
上一篇 2025-06-03 12:52
下一篇 2025-04-20 14:31

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/168136.html