Thread overview
__FILE__
Jul 26, 2021
workman
Jul 26, 2021
Adam D Ruppe
Jul 26, 2021
Stefan Koch
Aug 05, 2021
Ali Çehreli
Aug 05, 2021
Mathias LANG
July 26, 2021

file test.d:

-------------
module test;
import abc;
void doTest(){
	log!"test"();
}
-----------

file abc.d:
-------------
module abc;
import test;
void log(string fmt, int line = __LINE__, string path = __FILE__[0..$], A...)(A a) {
	import core.stdc.stdio;
	printf("[%s:%d] \n", path.ptr, line);
}
extern(C) int main() {
	doTest();
	return 0;
}

retult: [abc.d:4]

expect: [test.d:4]

July 26, 2021

On Monday, 26 July 2021 at 11:43:56 UTC, workman wrote:

>

FILE[0..$]

Why do you have that [0..$] there? It is probably breaking the FILE magic.

July 26, 2021

On Monday, 26 July 2021 at 12:01:23 UTC, Adam D Ruppe wrote:

>

On Monday, 26 July 2021 at 11:43:56 UTC, workman wrote:

>

FILE[0..$]

Why do you have that [0..$] there? It is probably breaking the FILE magic.

Correct.
The compiler has to evaluate the default argument as constant expression in order to use it as default value..
Therefore it evaluates (FILE)[0 ..$]you first eval FILE at CTFE within the module you are defining the function in.
And then you slice it from zero to length.

On the other hand if you use x = FILE it recognizes that as a special constant expression which can be put into the callsite directly.

August 04, 2021

On 7/26/21 1:05 PM, Stefan Koch wrote:

>

On Monday, 26 July 2021 at 12:01:23 UTC, Adam D Ruppe wrote:

>

On Monday, 26 July 2021 at 11:43:56 UTC, workman wrote:

>

FILE[0..$]

Why do you have that [0..$] there? It is probably breaking the FILE magic.

Correct.
The compiler has to evaluate the default argument as constant expression in order to use it as default value..

This is not true, you can use runtime calls as default values.

>

Therefore it evaluates (FILE)[0 ..$]you first eval FILE at CTFE within the module you are defining the function in.
And then you slice it from zero to length.

This might be how it is implemented, but it shouldn't be. __FILE__ should be usable inside any expression as a default value, which should expand to the call-site for the function (as usual).

But this has nothing to do with CTFE as far as I know.

-Steve

August 04, 2021
On 8/4/21 7:17 PM, Steven Schveighoffer wrote:

>> The compiler has to evaluate the default argument as constant
>> expression in order to use it as default value..
>
> This is not true, you can use runtime calls as default values.

Whaaaaat??? I just checked and it works! :)

string bar() {
  import std.process;
  return ("BAR" in environment) ? environment["BAR"] : null;
}

string foo(string s = bar()) {
  return s;
}

void main() {
  import std.stdio;
  writeln(foo("hello world"));
  writeln(foo());
}

Run e.g. with

$ BAR=whaaat ./deneme

I wonder whether this feature is thanks to 'lazy' parameters, which are actually delegates.

Ali

August 04, 2021

On 8/4/21 10:27 PM, Ali Çehreli wrote:

>

I wonder whether this feature is thanks to 'lazy' parameters, which are actually delegates.

No, the default parameters are used directly as if they were typed in at the call site (more or less, obviously the __FILE__ example is weird).

So:

writeln(foo());

is just like you did:

writeln(foo(bar()));

There are no lazy parameters involved.

-Steve

August 05, 2021

On Monday, 26 July 2021 at 11:43:56 UTC, workman wrote:

>

file test.d:

-------------
module test;
import abc;
void doTest(){
	log!"test"();
}
-----------

file abc.d:
-------------
module abc;
import test;
void log(string fmt, int line = __LINE__, string path = __FILE__[0..$], A...)(A a) {
	import core.stdc.stdio;
	printf("[%s:%d] \n", path.ptr, line);
}
extern(C) int main() {
	doTest();
	return 0;
}

retult: [abc.d:4]

expect: [test.d:4]

It's a known bug: https://issues.dlang.org/show_bug.cgi?id=18919
If you remove the slicing from __FILE__, it'll work as expected.