GCC 7.3.1中__BASE_FILE__展开为全路径而非文件名的原因咨询
嘿,这个问题我维护旧项目的时候也碰到过!其实这是GCC版本差异导致的行为区别——在你用的7.3.1版本里,__BASE_FILE__的设计就是展开为完整的源文件路径,和__FILE__行为一致。这个宏的行为是在GCC 8及以后的版本才做了调整,改成返回不带路径的文件名。
为什么会这样?
早期GCC对__BASE_FILE__的定义是“预处理阶段最初的输入文件名”,而实际编译流程中,GCC接收到的通常是带有完整路径的文件(比如通过绝对路径调用编译命令,或者makefile里传递了完整路径的源文件),所以这个宏就直接返回了完整路径。后来社区反馈这个行为不符合大家对“BASE_FILE”的直觉预期,才在更高版本中修改了它的实现。
几种可行的解决办法
如果你的项目只能停留在GCC 7.3.1,想要获取仅文件名的话,可以试试下面这些方法:
结合
__FILE__和字符串处理
利用C标准库的strrchr函数截取最后一个路径分隔符之后的部分,写个宏就能搞定:#include <string.h> #define SHORT_FILENAME (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)不管
__FILE__是完整路径还是纯文件名,这个宏都能正确返回文件名部分。用编译选项修改路径输出
GCC 5及以后支持-ffile-prefix-map选项,可以把指定的路径前缀替换为空。比如你的源码都在/home/yourname/project/src/目录下,编译时加上:gcc -ffile-prefix-map=/home/yourname/project/src/= your_source.c这样
__FILE__和__BASE_FILE__都会返回不带路径的文件名了,非常方便。编译时手动定义宏
如果你的构建脚本(比如makefile)能拿到源文件的文件名,也可以通过-D参数手动传递:gcc -DSOURCE_FILENAME=\"your_source.c\" your_source.c之后在代码里直接用
SOURCE_FILENAME宏就能得到纯文件名。
内容的提问来源于stack exchange,提问作者bananamana

