Open
Description
In this code (https://godbolt.org/z/dPhq718e5), Foo foo{}
ends up with an incorrect source_location
, while Foo foo{Potato{}
is fine.
It looks like using Bar::Bar
generates a default ctor for Foo
, which becomes the evaluation site for source_location::current()
.
I'm not a standards lawyer, but I didn't find any suggestion that what we're seeing here is the specified behavior. And for default arguments, the the clear intent of the C++ standard is for default arguments to be evaluated at the call site. The current behavior violates at least the spirit of that rule. It also breaks the typical source_location
-stamping technique.
#include <iostream>
#include <source_location>
struct Potato {};
struct Bar {
std::source_location sl_;
explicit Bar(Potato = {}, std::source_location sl = std::source_location::current())
: sl_(sl) {}
};
struct Foo : Bar { // `foo.sl_` points here on GCC & clang
using Bar::Bar;
}; // `foo.sl_` points here on MSVC
int main() {
Foo foo{}; // Why isn't `sl_` pointing here?
std::cout << "foo @ line " << foo.sl_.line() << std::endl;
Foo foo2{Potato{}}; // But this is fine!
std::cout << "foo2 @ line " << foo2.sl_.line() << std::endl;
return 0;
}