digitalmars.D.learn - `static` function ... cannot access variable in frame of ...
- Bastiaan Veelo (34/34) Jan 15 Hey people, I can use some help understanding why the last line
- Dukc (31/63) Jan 15 It seems that since you write `static` to the member function
- H. S. Teoh (8/17) Jan 15 [...]
- user1234 (4/21) Jan 15 I dont agree, problem is S_foo that get automagically
- user1234 (28/32) Jan 15 The two calls are not equivalent. To be equivalent you need to
- Bastiaan Veelo (9/11) Jan 15 Thanks all. I thought a static member function just isn't able to
- Steven Schveighoffer (10/20) Jan 15 As a workaround, you can alias the outer function in the struct:
- Bastiaan Veelo (4/12) Jan 16 It does! And it's good enough for me. Thanks a lot!
Hey people, I can use some help understanding why the last line produces a compile error. ```d import std.stdio; struct S { static void foo(alias len)() { writeln(len); } } void S_foo(alias len)() { writeln(len); } void main() { const five = 5; S_foo!five; // Fine S.foo!five; // Error } ``` The error is ``` onlineapp.d(7): Error: `static` function `onlineapp.main.foo!(5).foo` cannot access variable `five` in frame of function `D main` onlineapp.d(19): `five` declared here onlineapp.d(21): Error: template instance `onlineapp.main.foo!(5)` error instantiating ``` It seems to me this should just work. Thanks! --Bastiaan.
Jan 15
On Monday, 15 January 2024 at 18:16:44 UTC, Bastiaan Veelo wrote:Hey people, I can use some help understanding why the last line produces a compile error. ```d import std.stdio; struct S { static void foo(alias len)() { writeln(len); } } void S_foo(alias len)() { writeln(len); } void main() { const five = 5; S_foo!five; // Fine S.foo!five; // Error } ``` The error is ``` onlineapp.d(7): Error: `static` function `onlineapp.main.foo!(5).foo` cannot access variable `five` in frame of function `D main` onlineapp.d(19): `five` declared here onlineapp.d(21): Error: template instance `onlineapp.main.foo!(5)` error instantiating ``` It seems to me this should just work.It seems that since you write `static` to the member function signature, the compiler thinks the function shouldn't be allowed to have a hidden parameter that is needed to access `const five` from `foo`. At a first glance it seems this should be allowed, since `static` means "no access to the type or function enclosing the member function", which wouldn't appear to say anything about the hidden frame pointer to the `alias` context as opposed to the enclosing struct. But thinking about it, function templates are a shorthand for epnymous templates. I think the code get's rewritten to: ```D struct S { template foo(alias len) { static void foo() { writeln(len); } } } ``` . As you can see, in the rewritten form you actually are accessing the outer scope, which is exactly what `static` is supposed to prevent. On the other hand, if you move the template out of the struct you say this still works, even when it shouldn't according to my theory. I'm of the opinion that something in the compiler needs fixing here, but I'm not quite sure what.
Jan 15
On Mon, Jan 15, 2024 at 06:16:44PM +0000, Bastiaan Veelo via Digitalmars-d-learn wrote:Hey people, I can use some help understanding why the last line produces a compile error. ```d import std.stdio; struct S { static void foo(alias len)()[...] The trouble is with the `static` here. A context pointer is necessary in order to have access to the context of main() from the body of this function; but `static` precludes this possibility. T -- It is of the new things that men tire --- of fashions and proposals and improvements and change. It is the old things that startle and intoxicate. It is the old things that are young. -- G.K. Chesterton
Jan 15
On Monday, 15 January 2024 at 18:34:58 UTC, H. S. Teoh wrote:On Mon, Jan 15, 2024 at 06:16:44PM +0000, Bastiaan Veelo via Digitalmars-d-learn wrote:I dont agree, problem is S_foo that get automagically monomorphized in `main` scope. That's a very classic D problem.Hey people, I can use some help understanding why the last line produces a compile error. ```d import std.stdio; struct S { static void foo(alias len)()[...] The trouble is with the `static` here. A context pointer is necessary in order to have access to the context of main() from the body of this function; but `static` precludes this possibility. T
Jan 15
On Monday, 15 January 2024 at 18:16:44 UTC, Bastiaan Veelo wrote:[...] It seems to me this should just work. Thanks! --Bastiaan.The two calls are not equivalent. To be equivalent you need to set `S_foo` static too, otherwise `S_Foo` is instanciated in `main` scope, proof: ```d import std.stdio; struct S { static void foo(alias len)() { writeln(len); } } static void S_foo(alias len)() { writeln(len); } void main() { const five = 5; S_foo!five; // Error too now S.foo!five; // Error } ``` so what is passed as alias need to be static too. But to be frank, I agree this is a less ideal situation. There are like 20 bugs reports opened related to that. The way a non-static `S_foo` behaves is under-specified.
Jan 15
On Monday, 15 January 2024 at 18:43:43 UTC, user1234 wrote:The two calls are not equivalent.so what is passed as alias need to be static too.Thanks all. I thought a static member function just isn't able to access the instance of the struct, but as I understand now it is static all the way. What I am looking for is a way to have different structs that have a member function that has the same name in all of them, that is callable without a this pointer, and able to take an alias argument. That is probably asking too much. -- Bastiaan.
Jan 15
On Monday, 15 January 2024 at 22:23:27 UTC, Bastiaan Veelo wrote:On Monday, 15 January 2024 at 18:43:43 UTC, user1234 wrote:As a workaround, you can alias the outer function in the struct: ```d struct S { alias foo = S_foo; } ``` This might be less than ideal, but at least it works. -SteveThe two calls are not equivalent.so what is passed as alias need to be static too.Thanks all. I thought a static member function just isn't able to access the instance of the struct, but as I understand now it is static all the way. What I am looking for is a way to have different structs that have a member function that has the same name in all of them, that is callable without a this pointer, and able to take an alias argument. That is probably asking too much.
Jan 15
On Monday, 15 January 2024 at 23:06:00 UTC, Steven Schveighoffer wrote:As a workaround, you can alias the outer function in the struct: ```d struct S { alias foo = S_foo; } ``` This might be less than ideal, but at least it works.It does! And it's good enough for me. Thanks a lot! -- Bastiaan.
Jan 16