3

I tried the following first variant using GCC10 in C++20 mode:

consteval std::experimental::source_location there()
{
   return std::experimental::source_location::current(); // Line 3
}

void f(const std::experimental::source_location& a = there()) // Line 6
{
   std::cout << a.line() << std::endl;
}

int main(int pArgc, char* pArgv[])
{
   std::cout << there().line() << std::endl; // Line 13
   f(); // Line 14

   return 0;
}

I expected the following output:

13
14

but I got:

3
3

Then I tried the following second variant:

consteval std::experimental::source_location there(const std::experimental::source_location& a = std::experimental::source_location::current())
{
   return a; // Line 3
}

void f(const std::experimental::source_location& a = there()) // Line 6
{
   std::cout << a.line() << std::endl;
}

I expected the following output:

13
14

but I got:

13
6

Why does the code behave that way? Is there a way to make it behave as expected without using a pre-processor macro?

Update: The second variant with 'constexpr' or 'inline' instead of 'consteval' works fine with most recent GCC. So the remaining question is: Why doesn't 'consteval' work as well? I was told this isn't a standard issue but an implementation topic so I will re-tag this question as GCC.

Silicomancer
  • 8,604
  • 10
  • 63
  • 130
  • 1
    Because the call to `current` is on line 3? – bitmask Jun 28 '20 at 22:44
  • @bitmask Could you elaborate why the second call of the second variant shouldn't work? – Silicomancer Jul 02 '20 at 09:15
  • I would think because the object is constructed on line 6, not on line 14. I believe this is explained in [fdan](https://stackoverflow.com/users/10765031/fdan)'s answer below. – bitmask Jul 02 '20 at 09:50
  • I think fdan does not explain this. Or possibly he says the opposite. He says "Default function arguments are evaluated on the call-site". Well, if the default argument in Variant 2 / Line 1 is evaluated at call side, why shouldn't Variant 2 / Line 6 be evaluated at call-site too? In case of a default-argument function call used as a default argument I would have expected the mechanism to cascade. Maybe the language rules are different or maybe this is a bug in an experimental feature... – Silicomancer Jul 02 '20 at 10:57
  • I see your point. In that case, I cannot say. – bitmask Jul 02 '20 at 11:20

2 Answers2

3

source_location::current() always gives you the exact location from where it is called. The observed bahaviour is exactly how it should work.

Default function arguments are evaluated on the call-site. This is why the first call in the second example returns "13". This is also the only way how you should use source_location when wrapped in a function call (it doesn't make much sense otherwise).

local-ninja
  • 1,198
  • 4
  • 11
0

I turned out second variant is correct. On current GCC 12 it works fine.

Silicomancer
  • 8,604
  • 10
  • 63
  • 130