__FILE__ macro shows full path

177,345

Solution 1

Try

#include <string.h>

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

For Windows use '\\' instead of '/'.

Solution 2

Here's a tip if you're using cmake. From: http://public.kitware.com/pipermail/cmake/2013-January/053117.html

I'm copying the tip so it's all on this page:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__FILENAME__='\"$(subst
  ${CMAKE_SOURCE_DIR}/,,$(abspath $<))\"'")

If you're using GNU make, I see no reason you couldn't extend this to your own makefiles. For example, you might have a line like this:

CXX_FLAGS+=-D__FILENAME__='\"$(subst $(SOURCE_PREFIX)/,,$(abspath $<))\"'"

where $(SOURCE_PREFIX) is the prefix that you want to remove.

Then use __FILENAME__ in place of __FILE__.

Solution 3

I have just thought of a great solution to this that works with both source and header files, is very efficient and works on compile time in all platforms without compiler-specific extensions. This solution also preserves the relative directory structure of your project, so you know in which folder the file is in, and only relative to the root of your project.

The idea is to get the size of the source directory with your build tool and just add it to the __FILE__ macro, removing the directory entirely and only showing the file name starting at your source directory.

The following example is implemented using CMake, but there's no reason it wouldn't work with any other build tools, because the trick is very simple.

On the CMakeLists.txt file, define a macro that has the length of the path to your project on CMake:

# The additional / is important to remove the last character from the path.
# Note that it does not matter if the OS uses / or \, because we are only
# saving the path size.
string(LENGTH "${CMAKE_SOURCE_DIR}/" SOURCE_PATH_SIZE)
add_definitions("-DSOURCE_PATH_SIZE=${SOURCE_PATH_SIZE}")

On your source code, define a __FILENAME__ macro that just adds the source path size to the __FILE__ macro:

#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)

Then just use this new macro instead of the __FILE__ macro. This works because the __FILE__ path will always start with the path to your CMake source dir. By removing it from the __FILE__ string the preprocessor will take care of specifying the correct file name and it will all be relative to the root of your CMake project.

If you care about the performance, this is as efficient as using __FILE__, because both __FILE__ and SOURCE_PATH_SIZE are known compile time constants, so it can be optimized away by the compiler.

The only place where this would fail is if you're using this on generated files and they're on a off-source build folder. Then you'll probably have to create another macro using the CMAKE_BUILD_DIR variable instead of CMAKE_SOURCE_DIR.

Solution 4

GCC 8 now has the -fmacro-prefix-map and -ffile-prefix-map options:

-fmacro-prefix-map=old=new

When preprocessing files residing in directory old, expand the __FILE__ and __BASE_FILE__ macros as if the files resided in directory new instead. This can be used to change an absolute path to a relative path by using . for new which can result in more reproducible builds that are location independent. This option also affects __builtin_FILE() during compilation. See also -ffile-prefix-map.

-ffile-prefix-map=old=new

When compiling files residing in directory old, record any references to them in the result of the compilation as if the files resided in directory new instead. Specifying this option is equivalent to specifying all the individual -f*-prefix-map options. This can be used to make reproducible builds that are location independent. See also -fmacro-prefix-map and -fdebug-prefix-map.

Setting an invalid path for -ffile-prefix-map (-fdebug-prefix-map) will break debugging unless you tell your debugger how to map back. (gdb: set substitue-path, vscode: "sourceFileMap").

If your intent is to only clean up __FILE__ just use -fmacro-prefix-map.

Example: So for my Jenkins builds I will add -ffile-prefix-map=${WORKSPACE}/=/, and another to remove the local dev package install prefix.

NOTE Unfortunately the -ffile-prefix-map and -fmacro-prefix-map options are only available in GCC 8 onwards. For, say, GCC 5, we only have -fdebug-prefix-map which does not affect __FILE__.

Solution 5

At least for gcc, the value of __FILE__ is the file path as specified on the compiler's command line. If you compile file.c like this:

gcc -c /full/path/to/file.c

the __FILE__ will expand to "/full/path/to/file.c". If you instead do this:

cd /full/path/to
gcc -c file.c

then __FILE__ will expand to just "file.c".

This may or may not be practical.

The C standard does not require this behavior. All it says about __FILE__ is that it expands to "The presumed name of the current source file (a character string literal)".

An alternative is to use the #line directive. It overrides the current line number, and optionally the source file name. If you want to override the file name but leave the line number alone, use the __LINE__ macro.

For example, you can add this near the top of file.c:

#line __LINE__ "file.c"

The only problem with this is that it assigns the specified line number to the following line, and the first argument to #line has to be a digit-sequence so you can't do something like

#line (__LINE__-1) "file.c"  // This is invalid

Ensuring that the file name in the #line directive matches the actual name of the file is left as an exercise.

At least for gcc, this will also affect the file name reported in diagnostic messages.

Share:
177,345

Related videos on Youtube

mahmood
Author by

mahmood

Updated on July 15, 2022

Comments

  • mahmood
    mahmood almost 2 years

    The standard predefined macro __FILE__ available in C shows the full path to the file. Is there any way to short the path? I mean instead of

    /full/path/to/file.c
    

    I see

    to/file.c
    

    or

    file.c
    
    • cdleonard
      cdleonard over 12 years
      It would be really really great to find a preprocessor-only solution. I'm afraid that the suggestions based on string operations will execute at runtime.
    • Steve Jessop
      Steve Jessop over 12 years
      Since you're using gcc, I think you can change what __FILE__ contains by changing the filename you pass on the command line. So instead of gcc /full/path/to/file.c, try cd /full/path/to; gcc file.c; cd -;. Of course there's a bit more to it than that if you're relying on gcc's current directory for the include path or output file location. Edit: the gcc docs suggest that it's the full path, not the input file name argument, but that's not what I'm seeing for gcc 4.5.3 on Cygwin. So you may as well try it on Linux and see.
    • RBerteig
      RBerteig over 11 years
      GCC 4.5.1 (built for arm-none-eabi specifically) uses the exact text of the file name on its command line. In my case it was the IDE's fault for invoking GCC with all file names fully qualified instead of putting the current directory somewhere sensible (location of the project file, perhaps?) or configurable and using relative paths from there. I suspect a lot of IDEs do that (especially on Windows) out of some sort of discomfort related to explaining where the "current" directory really is for a GUI app.
    • Chan Kim
      Chan Kim over 9 years
      @SteveJessop - hope you read this comment. I have a situation where I see __FILE__ printed as ../../../../../../../../rtems/c/src/lib/libbsp/sparc/leon2/.‌​./../shared/bootcard‌​.c and I want to know where gcc compiled the file such that this file is relatively located like it is shown.
    • Prof. Falken
      Prof. Falken almost 9 years
      This question is not a dupe of the linked one. For one, the linked one is about C++, and the answers consequently delves into C++ macro esoterica. Second, there is nothing in OP's question which mandates a macro solution. It only solemnly points out a problem and asks an open ended question.
    • Daniel H
      Daniel H about 6 years
      I know this ask is years old, but this will be possible to do at compile time in GCC 9 (I don't think that made it onto the 8 branch, but I could be wrong).
    • user3629249
      user3629249 over 5 years
      You could use the basename() function to extract just the current file name for printing
    • Andry
      Andry almost 5 years
      With at least the C++11 you can do it at compile time instead of in the preprocessor: stackoverflow.com/questions/8487986/file-macro-shows-full-pa‌​th/…
    • Trevor Boyd Smith
      Trevor Boyd Smith almost 5 years
      FYI here is a 4 line c++11 solution using compile-time constexpr tested with g++ version 4.8.5: stackoverflow.com/a/38237385/52074
  • Steve Jessop
    Steve Jessop over 12 years
    @mahmood: char file_copy[] = __FILE__; const char *filename = basename(__FILE__);. The reason for the copy is that basename can modify the input string. You also have to watch out that the result pointer is only good until basename is called again. This means it isn't thread-safe.
  • Steve Jessop
    Steve Jessop over 12 years
    the strrchr answer could plausibly be computed at compile-time, although of course still not by the preprocessor. I don't know whether gcc actually does it, I haven't checked, but I'm pretty sure that it does compute strlen of string literals at compile-time.
  • Steve Jessop
    Steve Jessop over 12 years
    @mahmood: strrchr returns a pointer to the / (or a null pointer if it doesn't find a /), so +1 means that the resulting pointer is one character further on. Without it, the result string would be /file.c instead of file.c.
  • Sean
    Sean over 12 years
    @Steve - maybe, but that's a big dependency on compiler specific behaviour.
  • Steve Jessop
    Steve Jessop over 12 years
    I don't think it is a big dependency, because I very much doubt that this code is performance-critical. And if it is, move it out of the loop. In cases where this is a huge deal, because you absolutely need a string literal containing just the basename, you could perhaps compute the right string at build time by running some script over the source.
  • mahmood
    mahmood over 12 years
    makes no difference. I used __FILE__ and __BASE_FILE__ however they both show full path to file
  • Prof. Falken
    Prof. Falken over 12 years
    @SteveJessop, ah I forgot. True.
  • user1703401
    user1703401 over 12 years
    / is a valid path separator in Windows.
  • ziu
    ziu over 12 years
    how do you invoke the compiler ?
  • Steve Jessop
    Steve Jessop over 12 years
    @Amigable: to be fair, I suspect that basename in fact will not modify the input string that results from __FILE__, because the input string doesn't have a / at the end and so there's no need for modification. So you might get away with it, but I figure the first time someone sees basename, they should see it with all the restrictions.
  • ziu
    ziu over 12 years
    Then I bet SCONS is calling gcc like this gcc /absolute/path/to/file.c. If you find a way to change this behavior (opening another question on SO, lol?), you do not need to modify the string at runtime
  • Prof. Falken
    Prof. Falken over 12 years
    @SteveJessop the BSd man page for basename() mention that legacy version of basename() takes a const char* and does not modify the string. The linux man page mentions nothing about const but mentions that it can return a part of the argument string. So, best be conservative dealing with basename().
  • Prof. Falken
    Prof. Falken over 12 years
    But I think all of path has to be with forward slashes.
  • RBerteig
    RBerteig over 11 years
    / is a valid path separator in file names passed to CreateFile() and so forth. However, that doesn't always mean that you can use / just anywhere in Windows since there is a tradition (inherited from CPM) of using / as the argument lead in at the command prompt. But a quality tool would be careful to split file names at both slash and backslash characters to avoid any problems for folks that do manage to use /.
  • RBerteig
    RBerteig over 11 years
    @AmigableClarkKant, no you can mix both separators in the same file name.
  • RBerteig
    RBerteig over 11 years
    It may not be performance critical, but it can easily be seen as privacy critical. There's no real good reason for revealing my per-customer organizational practices in strings frozen into a released EXE file. Worse, for applications created on behalf of a customer, those strings might reveal things my customer might prefer not to, such as not being the author of their own product. Since __FILE__ is invoked implicitly by assert(), this leak can occur without any other overt act.
  • tchen
    tchen over 11 years
    @RBerteig the basename of __FILE__ itself may also reveal things the customer might prefer not to, so using __FILE__ anywhere at all -- whether it contains the full absolute pathname or just the basename -- has the same issues that you pointed out. In this situation all output will need to be scrutinized and a special API should be introduced for output to customers. The rest of the output should be dumped to /dev/NULL or stdout and stderr should be closed. :-)
  • Czarek Tomczak
    Czarek Tomczak over 11 years
    __FILE__ may contain mixed separators, in my case I see c:\phpdesktop\phpdesktop-src\phpdesktop-msie\msie/internet_f‌​eatures.h. Anyone have a macro for that?
  • Keith Thompson
    Keith Thompson almost 11 years
    Defining a macro named FILE is a really bad idea if you include <stdio.h>.
  • alexander golks
    alexander golks almost 11 years
    good to know. i just wanted to show Czarek my \\ / solution, so i don't bothered with naming schemes.
  • thegreendroid
    thegreendroid almost 11 years
    This is a great idea! Much better than pulling in the standard string library to trim the filename, which isn't really an option on most embedded platforms.
  • JeremyP
    JeremyP almost 11 years
    If your platform supports it char* fileName = basename(__FILE__); It's definitely there in Linux and OS X, don't know about Windows though.
  • ed9w2in6
    ed9w2in6 over 10 years
    I am afraid then this doesn't work for the FILE referenced in header file.
  • nhed
    nhed about 10 years
    Agree with @BaiyanHuang but not sure that the comment is clear. __FILE__ is not a simple preprocessor symbol, it changes to the current file is often used for emitting the name of the current file (header or source module). This __FILENAME__ would only have the outermost source
  • Marc Plano-Lesay
    Marc Plano-Lesay over 9 years
    How would you remove the file extension with this? Keeping only basename?
  • Patrick
    Patrick over 9 years
    @Kernald Try using $(basename $(abspath $<)) instead of $(abspath $<)
  • Marc Plano-Lesay
    Marc Plano-Lesay over 9 years
    Well, that was… unexpectedly simple! Thanks. It works like a charm.
  • Saher Ahwal
    Saher Ahwal over 9 years
    I tried that with '\\' for windows and it didn't work , can you please help me see what I am missing stackoverflow.com/questions/27493937/base-file-name-from-fil‌​e
  • oohtj
    oohtj over 9 years
    Great idea! That solved my file path too long in log file problem.
  • Colin D Bennett
    Colin D Bennett over 9 years
    This answer's solution is not portable since it uses Bourne shell escapes. Better to use CMake to implement it in a clean and portable way. See define_file_basename_for_sources macro answer here.
  • firegurafiku
    firegurafiku about 9 years
    @thegreendroid: there is nothing wrong with using 'strrchr' even on an embedded platform as this function just seeks memory and pretty fast. Furthermore, it's also a part of of both C89 and C99.
  • Julian F. Weinert
    Julian F. Weinert about 9 years
    This does work indeed, but unfortunately you'll still find the full path in the executable.
  • Prof. Falken
    Prof. Falken almost 9 years
    @SteveJessop, hehe, I only now after looking at your comment carefully, after four years, realize that / at the end of the string means basename may have a good reason to modify its argument.
  • ɲeuroburɳ
    ɲeuroburɳ almost 9 years
    This could be shortened to strrchr("/" __FILE__, '/') + 1. By prepending "/" to __FILE__, strrchr is be guaranteed to find something, and thus the conditional ?: is no longer needed.
  • Quuxplusone
    Quuxplusone over 8 years
    This answer is 100% wrong. __BASE_FILE__ (as the docs say, albeit unclearly) produces the name of the file specified on the command line, e.g. test.c or /tmp/test.c depending on how you invoked the compiler. That's exactly the same thing as __FILE__, except if you're inside a header file, in which case __FILE__ produces the name of the current file (e.g. foo.h) whereas __BASE_FILE__ continues to produce test.c.
  • Oz.
    Oz. over 8 years
    Also works great if you use strstr(__FILE__, "my_source_directory"). With that you can keep the paths within the project.
  • Keith Thompson
    Keith Thompson over 8 years
    push_macro and pop_macro are non-standard. (gcc supports them for compatibility with Microsoft Windows compilers.) In any case, there's no point in pushing and popping the definition of __FILE__; the restored value won't be used after the end of the source file anyway. A cleaner way to change the value of __FILE__ is #line __LINE__ "foobar.c"
  • Keith Thompson
    Keith Thompson over 8 years
    And this causes an internal error in gcc's preprocessor. gcc.gnu.org/bugzilla/show_bug.cgi?id=69665
  • Andrew Henle
    Andrew Henle over 7 years
    char* fileName = basename(__FILE__); is dangerous. basename() can modify its argument string. Per POSIX: The basename() function may modify the string pointed to by path That could result in a SEGV if the string __FILE__ expands to is read-only. Also see man7.org/linux/man-pages/man3/basename.3.html
  • Digital Trauma
    Digital Trauma about 7 years
    Cool answer. You need to use at least -O1 to use this to be compile-time.
  • ctuffli
    ctuffli almost 7 years
    The GNU Make variant of this is CFLAGS += -D__FILENAME__=\"$(notdir $<)\"
  • RenatoUtsch
    RenatoUtsch over 6 years
    There is a way to do it purely on compile time, you just need to be a little bit smart with the build configuration. See my answer for more details.
  • mrtumnus
    mrtumnus over 6 years
    Isn't this backwards? You want to find the last occurrence of '/', which means you should start with the sizeof(s) > 2 check first. Also, this did not work at compile-time for me, at -Os. The full path strings were present in the output binary.
  • mrtumnus
    mrtumnus over 6 years
    @firegurafiku On embedded platforms, code size is often more of a constraint than speed. If you have debug statements in each file, that can quickly balloon file-size up with full-path strings. I'm dealing with such a platform at the moment, and referencing __FILE__ everywhere is blowing out of code-space.
  • mrtumnus
    mrtumnus over 6 years
    You can easily avoid a second call to strrchr with a local variable: #define __FILENAME__ ({const char * pStr = strrchr(__FILE__, '/'); pStr ? pStr + 1 : __FILE__;})
  • alex
    alex about 6 years
    For those who interested both strrchr and strstr work in compile time in this case, tested with gcc 6.3.0 -O2.
  • Technophile
    Technophile about 6 years
    May want to check both '/' and '\', depending on platform.
  • lollo
    lollo about 6 years
    Don't work with cmake + ninja: ninja: error: build.ninja:221: bad $-escape (literal $ must be written as $$)
  • Trevor Boyd Smith
    Trevor Boyd Smith almost 6 years
    @AndrewSelivanov how did you verify that this is done at compile time?
  • alex
    alex almost 6 years
    @TrevorBoydSmith built with --save-temps and inspected generated code
  • Daniel
    Daniel almost 6 years
    I didn't understand this at first. I coded up examples and ran them against gcc and clang and they work. I also experiment with just appending various literal numeric values, and that behaves as I expected. Then it finally dawned on me. __FILE__ is a pointer to an array of bytes. So adding a numeric literal is just pointer addition. Very clever @RenatoUtsch
  • Pietro
    Pietro over 5 years
    A detail: the "__" pre- and postfix is a notation reserved to the implementation.
  • Pietro
    Pietro over 5 years
    @mrtumnus - I get the (pedantic) warning: "ISO C++ forbids braced-groups within expressions", pointing to the first parenthesis.
  • mrtumnus
    mrtumnus over 5 years
    @Pietro Yeah, the extra parens probably aren't necessary. They carried over from the OP's original statement.
  • elklepo
    elklepo over 5 years
    Keith Thompson it is great solution, thank You. The only problem is that it seems that this macro cuts __LINE__ value by one. So __LINE__ written in line x gest evaluated to x-1. At least with gcc 5.4.
  • Keith Thompson
    Keith Thompson over 5 years
    @Klepak: You're right, and that's standard behavior. The directive "causes the implementation to behave as if the following sequence of source lines begins with a source line that has a line number as specified by the digit sequence". And it has to be a digit-sequence, so you can't use #line __LINE__-1, "file.c". I'll update my answer.
  • l33t
    l33t over 5 years
    I wonder if the optimizer is able to optimize the calls to strchr and strrchr. Not to mention references to the __FILENAME__ macro. If not, this solution is 100% bloat.
  • Lekensteyn
    Lekensteyn over 5 years
    Option -ffile-prefix-map indeed implies both -fdebug-prefix-map and -fmacro-prefix-map options. See also the references at reproducible-builds.org/docs/build-path The GCC bug that tracks -fmacro-prefix-map and -ffile-prefix-map is gcc.gnu.org/bugzilla/show_bug.cgi?id=70268
  • Andry
    Andry over 5 years
    It works only if a source file is under cmake list directory. If a source file is outside then it will break, might with access outside of a literal string. So be careful with that.
  • Tarion
    Tarion about 5 years
    It actually does not reduce the code size. I guess the whole path is still compiled into the binary, just the pointer is modified.
  • RenatoUtsch
    RenatoUtsch about 5 years
    Both the __FILE__ macro and the SOURCE_PATH_SIZE macros are constants known at compile time. I'd expect modern optimizing compilers to be able to detect that part of the string is not used and simply remove it from the binary. Anyway, I don't think these few bytes would make a significant difference in the binary size, so I wouldn't really care about that.
  • Gregory Pakosz
    Gregory Pakosz about 5 years
    ⚠️when you follow this method, you break Visual Studio's (as of 2019) /MP parallel compilation. As it batches compilation and having per-file compiling options degrades to batches of size 1. See randomascii.wordpress.com/2014/03/22/…
  • mike.dld
    mike.dld almost 5 years
    CMake 3.4+ documentation states that "This variable has no effect. The partially implemented effect it had in previous releases was removed in CMake 3.4." If it worked for you with 3.13, there's another reason for that.
  • Paul Stelian
    Paul Stelian over 4 years
    @RenatoUtsch The project I'm working on has a change which just specifies the file name, but has the disadvantage of giving the C file name to the header too. The change was made in order to get reproducible builds. So with gcc with -O2, would the string be indeed optimized and the build made reproducible?
  • RenatoUtsch
    RenatoUtsch over 4 years
    I'd expect that, but you'll have to test it out for yourself.
  • Franklin Yu
    Franklin Yu over 4 years
    How would it be for other compilers like Clang, MSVC, or Intel C Compiler?
  • Roman
    Roman over 4 years
    Man, that's beautiful and it works, thank you! No idea why this answer is so underrated.
  • chqrlie
    chqrlie about 4 years
    Why do you need std::max<const char*> instead of just std::max?
  • chqrlie
    chqrlie about 4 years
    This does not work for contents coming from include files.
  • Levi.G
    Levi.G about 4 years
    can you post some code? A common case is to set variables in local scope and use it in another.
  • chqrlie
    chqrlie about 4 years
    For example if you use __FILE__ with your definition to produce a diagnostic in an inline function defined in a header file, the runtime diagnostic will report the name of the file passed to the compiler instead of the name of the include file, whereas the line number would refer to the include file.
  • Levi.G
    Levi.G almost 4 years
    yes, it designed to be that, for the most common usage is #define LOG(fmt, args...) printf("%s " fmt, __FILE__, ##args). when using the LOG() macro, you do not really want to see log.h in messages. after all, the __FILE__ macro is expanded in every C/Cpp file (compile unit) instead of the included files.
  • twex
    twex over 3 years
    I got "Using $< in a non-suffix rule context is a GNUmake idiom" from a non-GNU make. I used $(notdir $file) instead.
  • Laurie Stearn
    Laurie Stearn over 3 years
    in VS2019, /FC is forced if using the Edit & Continue /ZI d/b.
  • Mark Rotteveel
    Mark Rotteveel about 3 years
    Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
  • icebp
    icebp about 3 years
    In addition to working only with the make generator, this will no longer work starting with CMake 3.20. An alternative that is still make-specific is: set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__FILENAME__='\"$(notdir $(abspath $@))\"'")
  • Matt Eding
    Matt Eding about 3 years
    At line 0 of a file, I just do: #line 2 "name.cpp". Also as a side note it is nice to know that it does not contaminate other files that #include it (at least on MSVC)
  • psyched
    psyched about 3 years
    You can define one more helper macro #define LEAF(FN) (&FN[UTILITY_CONST_EXPR_VALUE(get_file_name_offset(FN))]) and use it like this printf("%s\n", LEAF(__FILE__));
  • Hadatko
    Hadatko almost 3 years
    Nope this is not purely compile time solution.
  • Steven Lu
    Steven Lu almost 3 years
    I can confirm this answer does not work and broke my cmakelists, I got c++: fatal error: no input files. I can also confirm that the above linked helper from this link works great. Thanks @ColinDBennett
  • Burak
    Burak over 2 years
    Good solution except std::max requires <algorithm> which I would rather not include in a header file. Another option can be checking platform by #ifdef _WIN32 since __FILE__ will have consistent separator characters.
  • LongLT
    LongLT over 2 years
    Damn, amazing solution
  • automorphic
    automorphic over 2 years
    This should be the answer. It doesn't require cmake, modifying the makefile, or runtime computation. And it can be used by a new FILENAME macro to make it intuitive: #define __FILENAME__ (__FILE__ + get_file_name_offset(__FILE__))
  • automorphic
    automorphic over 2 years
    Works, but leaves subdirs relative to dir with CMakeLists.txt. @Andry's solution leaves just the filename.
  • Cem Polat
    Cem Polat about 2 years
    Without the /FC option, FILE uses the relative path instead of the absolute path. Although it is shorter, it is not a "file name without path" solution.
  • Ramón Gil Moreno
    Ramón Gil Moreno about 2 years
    The fact that the question uses "/" as path separator points to a non-Windows compiler. I doubt @mahmood was using MSVC; some comments state he was using gcc but I could not locate where he said so.
  • Luc Bloom
    Luc Bloom about 2 years
    @Burak then any other simple "max" function will suffice. #define PATH_SEPARATOR will also help of course.
  • ocroquette
    ocroquette almost 2 years
    If your compiler supports this, like any decently recent version of GCC or Clang does, you should use this instead of the other solutions. It is so much more elegant and lightweight.