https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77488
Bug ID: 77488 Summary: Proposal for __FILENAME_ONLY__ Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: preprocessor Assignee: unassigned at gcc dot gnu.org Reporter: rdiezmail-gcc at yahoo dot de Target Milestone: --- Hi all: I am writing embedded software for a memory-constraint embedded target. However, I would still like to use assert() in debug builds to help debug the software. The assert() macro includes in the final binary a lot of text, like the source code filename, the function name and assert expression. So much text is blowing my memory budget. This is newlib's definition of assert: # define assert(__e) ((__e) ? (void)0 : __assert_func (__FILE__, __LINE__, \ __ASSERT_FUNC, #__e)) Most of the time, I only need a filename and a line number, so I wrote a small patch that builds my toolchain without the rest. The patch is here: https://github.com/rdiez/JtagDue/blob/master/Toolchain/NewlibSmallerAssert.patch The trouble is, the only built-in symbol that yields the filename of a source file is __FILE__, which includes the full path. But the full path is often too long, and its length varies depending on where the software is built, so the generated binary may or may not fit in the target's program memory depending on the source code's path length at compilation time. This is not obvious and rather annoying. For example, when the overnight build suddently blows the flash memory (program memory) budget, it is not obvious the reason is that the source path on the server is longer than on the developer's PC. A related question has been asked before: __FILE__ macro shows full path https://stackoverflow.com/questions/8487986/file-macro-shows-full-path I cannot easily control the path depth, because I am using the autotools in my project in order to generate the makefiles. In any case, the advise regarding filenames on makefiles and so on is often that you should be using absolute paths in order to avoid surprises. The following suggested solution does not work for me either: #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) Function strrchr() is recognised as a GCC intrinsic, but it is not optimised away at compilation time like the strlen() case. That alone could be an improvement to GCC. A new predefined symbol like __FILENAME_ONLY__, which should yield __FILE__ without the full path, would be the most comfortable solution for me. Sure, some filenames are going to have the same name, but it is fairly easy to tell which assert failed from a filename and a line number even if 2 or 3 source files happen to have the same name. A more advanced solution would be to have predefined symbol like __FILENAME_WITHOUT_PREFIX__( filename, prefix_to_remove ), but I do not think that this is worth the trouble. I have seen source code bases where each .cpp file got assigned a textual ID or a number manually, so that the strings passed to assert() are always of a determined length, but this is a pain to maintain. Every time you add a new source file, you need to update the ID table, which tends to trigger a recompilation of all files. But maybe the compiler could automatically assign an ID per file and then generate a map file with those IDs for later look-up. Or maybe I could write an __assert_func() that prints the __builtin_return_address() instead of a source filename, so that I can manually look-up the function's name in the generated linker .map file. However, I have to enable some optimisation even on debug builds for my memory-constrained targets, and I wonder if even minor optimisations could render those addresses meaningless for the purposes of correlating to a source code line. Any other ideas? Thanks in advance, rdiez