gpt4 book ai didi

c++ - 如何在编译时提取没有路径和后缀的源文件名?

转载 作者:行者123 更新时间:2023-11-30 16:36:59 27 4
gpt4 key购买 nike

同时使用 gcc 和 -std=c11 以及 g++ 和 -std=c++14。

例如对于名为 src/dir/Hello.cxx 的文件它应该扩展到类似的内容:

const char basename[] = "Hello";

const char basename[] = getStaticBasename(__FILE__);

getStaticBasename()是一个宏(对于 C 源代码)或 constexpr 函数(对于 C++ 源代码),其结果为“Hello”。

我必须避免将字符串从 __FILE__ 中分割出来。在运行时,因为路径和后缀不能以任何方式编译成可执行文件。

该解决方案必须不依赖于 boost 等大型库。

由于我没有 makefile,解决方案如 this不能用于我的情况。

有解决办法吗?

编辑于2015年7月2日:

  • 我对编译器和链接器的调用方式没有影响(有时通过 makefile,有时通过命令行,或某些 IDE(Eclipse CDT 管理的 make、Crossworks、Xcode 等)。因此解决方案只需采用代码形式。
  • 我的用例是为小型日志记录解决方案提供某种“通用区域标识符”。应用程序代码(使用我的记录器)应该仅 #include <Joe/Logger.h>并在后来的电话中,例如LOG_DEBUG(...)我将隐式地使用自动生成的“通用区域标识符”。
  • 我当前的解决方案是应用程序代码必须声明 JOE_LOG_FILE_REGION(Hello); (在 #include <Joe/Logger.h> 之后)在它可以放置 LOG_DEBUG(...) 之前在其代码中。

最佳答案

1。 gcc内置函数可以在编译时获取完整路径的文件名。

#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)

#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)

2。 c++11 constexpr 也可以在编译时执行此操作。

c++11 constexpr 函数只能使用 return 语句。

示例:

#include <stdio.h>

constexpr const char* str_end(const char *str) {
return *str ? str_end(str + 1) : str;
}

constexpr bool str_slant(const char *str) {
return *str == '/' ? true : (*str ? str_slant(str + 1) : false);
}

constexpr const char* r_slant(const char* str) {
return *str == '/' ? (str + 1) : r_slant(str - 1);
}
constexpr const char* file_name(const char* str) {
return str_slant(str) ? r_slant(str_end(str)) : str;
}

int main() {
constexpr const char *const_file = file_name(__FILE__);
puts(const_file);
return 0;
}

源文件名为foo/foo1/foo2/foo3/foo4.cpp

使用 g++ -o foo.exe foo/foo1/foo2/foo3/foo4.cpp -std=c++11 --save-temps 编译此文件。

你可以看到这个。

.file   "foo4.cpp"
.section .rodata
.LC0:
.string "foo/foo1/foo2/foo3/foo4.cpp"
.text
.globl main
.type main, @function
main:
.LFB4:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq $.LC0+19, -8(%rbp)
movl $.LC0+19, %edi
call puts
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE4:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
.section .note.GNU-stack,"",@progbits

movl $.LC0+19, %edi .LC0 + 19 是不带路径和后缀的文件名字符串的地址

3。 c++14 constexpr 函数可以通过简单的方式做到这一点

#include <iostream>

constexpr const char* file_name(const char* path) {
const char* file = path;
while (*path) {
if (*path++ == '/') {
file = path;
}
}
return file;
}

int main() {
constexpr const char* file = file_name(__FILE__);
std::cout << file << std::endl;
return 0;
}

c++14 constexpr 函数可以使用循环和局部变量。

file_name 函数将在编译时替换为 const char * 的地址。〜

关于c++ - 如何在编译时提取没有路径和后缀的源文件名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48201949/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com