1

I know, that my question is similar to this: Passing the caller __FILE__ __LINE__ to a function without using macro

But I'm wondering, why there is no c++ equivalent of caller file and line passing to a function.

Having classes, templates, default arguments and more strict const-correctness makes a lot of macro usage obsolete, but when I want to pass caller file and line to a function, I will go in trouble for 2 reasons: 1. Default arguments (hard to replace all kinds of calls with a macro), 2. Macros break class member name scope. (startTimer macro would be global)

Thinking about the default arguments to functions, why are there no default-args-style replacements for FILE and LINE macros? It could be done like this:

void startTimer(int type, int id=0, string file = _CALLER_::FILE, int line = _CALLER_::LINE)

If the compiler, while looking for function calls of startTimer, can replace the id parameter with 0, where it isn't mentioned, it should be possible to replace file and line with the corresponding CALLER members, which in this example depend on the file, being processed, and the line where the call is made - something that the compiler knows while parsing a cpp file.

Knowing the caller of a member function may be useful for debugging - on which file/line has something been called, which leads to a problem later.

7
  • 2
    __FILE__ is not a macro. And there's no way to answer this question. The only answer to "why doesn't C++ have X feature" is "because you haven't proposed it to the working group yet". Commented Apr 11, 2014 at 11:16
  • @Lightness Races in Orbit: 1. ISO C++ 2012 draft, 16.8 Predefined macro names: "The following macro names shall be defined by the implementation: [...] _ _ FILE _ _ [...]" 2. Often there is a reason why something hasn't been suggested or accepted yet, which would be interesting to know. Commented Apr 11, 2014 at 11:27
  • possible duplicate of Can I default a function argument to the value of __FILE__ at the caller? Commented Apr 11, 2014 at 11:32
  • Your question may be inspired by the recent caller information feature in .NET, cf. msdn.microsoft.com/en-us/library/hh534540.aspx. Its implementation in C# (CLR?) is based on attributes. A similar functionality in the C/C++ world could perhaps be achieved by using pragmas. But the semantics of pragmas are, afaics, not specified by the standard beyond the statement that their effect is implementation-defined. In other words their purpose is specifically to communicate with specific implementations, not to to add standard language features. Commented Apr 11, 2014 at 11:38
  • @PeterSchneider: Whoops, I was thinking of __function__, of course. The rest of my comment stands. BTW you should cite standards, not drafts. Commented Apr 11, 2014 at 11:58

2 Answers 2

4

I think to have the feature optional, i.e. have it part of the function declaration the way you suggest, is not easy or not possible. The compiler must insert the needed information at, well, compile time (because file and line information are lost at run time), but at that time it may not know at all which function will be called in the case of virtual member functions or even plain old function pointers which get assigned in unpredictable ways.

But it would perhaps be possible to have all functions receive two hidden and undeclared parameters, the same way that member functions receive a hidden this pointer. In that scenario the compiler doesn't need to know which function is called because all functions receive the hidden caller line and file parameters.

Even if that is possible, I see the following problems:

  1. That's obviously a major change to an implementation, and probably to the language. (I'm not sure whether it could be done behind the scenes by an implementation which still claims to comply with today's standard.) It would be impossible in C for all practical purposes because it would break existing ABIs (unless Microsoft does it ;-) ). That would be less of an issue in C++ where ABI compatibility is much worse anyway.
  2. It may be a performance problem that two parameters need to be passed to each function although they aren't often needed at all, and it may perhaps even be a memory problem on tiny (e.g. embedded) systems because the stack would grow faster. (Of course you could claim that they shouldn't build up such a deep stack to begin with, but still.)

If you consider that the functionality is available right now in the shape of a macro (with the only downside of name space pollution which is totally manageable), the benefit/effort ratio simply isn't good enough, is my guess.

Sign up to request clarification or add additional context in comments.

Comments

2

There we are, c++20 introduces the std::source_location. Exactly what you wished, only the usage is a bit different. It holds all the information that those macros covered (file name, line number, function name), but doesn't suffer from the macro expansion.

Example from cppreference:

#include <iostream>
#include <source_location>
#include <string_view>
 
void log(const std::string_view message,
         const std::source_location location =
               std::source_location::current())
{
    std::clog << "file: "
              << location.file_name() << '('
              << location.line() << ':'
              << location.column() << ") `"
              << location.function_name() << "`: "
              << message << '\n';
}
 
template<typename T>
void fun(T x)
{
    log(x); // line 20
}
 
int main(int, char*[])
{
    log("Hello world!"); // line 25
    fun("Hello C++20!");
}

Output:

file: main.cpp(25:8) int main(int, char**): Hello world!
file: main.cpp(20:8) void fun(T) [with T = const char*]: Hello C++20!

2 Comments

Could one of these be closed as a duplicate? 👀
Go for it! I think the question OP linked is a perfect duplicate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.