Using both gcc with -std=c11 and g++ with -std=c++14.
E.g. for a file named src/dir/Hello.cxx
it should expand to something like e.g.:
const char basename[] = "Hello";
or
const char basename[] = getStaticBasename(__FILE__);
as where getStaticBasename()
is a macro (for C sources) or constexpr function (for C++ sources) which results to "Hello".
I have to avoid splitting the string from __FILE__
at runtime, because the path and suffix must not be compiled into the executable in any way.
The solution must be without dependencies to huge libraries such as boost.
As I have no makefiles, solutions like this cannot be used in my case.
Did one have a solution for that?
Edit 2015-07-02:
#include <Joe/Logger.h>
and within the later calls to e.g. LOG_DEBUG(...)
I'll implicitely take use of the automatically generated "generic region identifier".JOE_LOG_FILE_REGION(Hello);
(after #include <Joe/Logger.h>
) before it could place LOG_DEBUG(...)
in its code.#define __FILENAME__ (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
or
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
c++11 constexpr function can only use a return-statement.
example:
#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;
}
source file name is foo/foo1/foo2/foo3/foo4.cpp
use g++ -o foo.exe foo/foo1/foo2/foo3/foo4.cpp -std=c++11 --save-temps
to compile this file.
you can see this.
.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 is the address of file name string without path and suffix
#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 function can use loop and local variable.
the file_name
function will replace with a address of const char *
at compiler time.
~