Thread overview
Re: Struct hidden context pointers
Jul 06, 2013
Jonathan M Davis
Jul 07, 2013
Iain Buclaw
Jul 07, 2013
Jonathan M Davis
Jul 08, 2013
H. S. Teoh
Jul 08, 2013
Jonathan M Davis
July 06, 2013
On Saturday, July 06, 2013 14:13:29 H. S. Teoh wrote:
> Today, while trying to track down what I thought was a bug in GDC, I discovered the following, which looks suspiciously like a bug / quality of implementation issue:
> 
> 	import std.conv;
> 
> 	// Function to test if T is independently instantiable.
> 	void f(T)() {
> 	    T t;
> 	}
> 
> 	unittest {
> 	    struct S {
> 		int x;
> 	    }
> 	    struct T {
> 		int y;
> 		bool f() { return true; }
> 	    }
> 
> 	    f!S();	// works
> 	    f!T();	// test.d(4): Error: cannot access frame pointer of
> test.__unittestL7_1.T // test.d(17): Error: template instance test.f!(T)
> error instantiating
> 
> 	}
> 	void main() { }
> 
> 
> The thing is, nowhere in the definition of T is any frame pointer required; apparently the frame pointer is triggered by the existence of any methods in the struct.
> 
> Shouldn't the frame pointer be generated only if f() actually tries to access something outside of the definition of T?

Probably, but that's arguably an optimization. Regardless, marking it as static will force the issue.

- Jonathan M Davis
July 07, 2013
On 6 July 2013 22:41, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> On Saturday, July 06, 2013 14:13:29 H. S. Teoh wrote:
>>
>> Shouldn't the frame pointer be generated only if f() actually tries to access something outside of the definition of T?
>
> Probably, but that's arguably an optimization. Regardless, marking it as static will force the issue.
>

An optimization that is on similar boundaries as virtual by default. :)

What I see is a non-POD nested struct, one that requires a 'this' pointer to the outer context to be set-up.  However I know that gdc probably smarter than the front-end implementation about this in that it (the gcc glue part of the front-end) will acknowledge that there's no outer context and will set the outer 'this' pointer to null. Whilst still producing an error if a non-static member tries to access it's outer context in this situation.

--
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
July 07, 2013
On Sunday, July 07, 2013 14:30:12 Iain Buclaw wrote:
> On 6 July 2013 22:41, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > On Saturday, July 06, 2013 14:13:29 H. S. Teoh wrote:
> >> Shouldn't the frame pointer be generated only if f() actually tries to access something outside of the definition of T?
> > 
> > Probably, but that's arguably an optimization. Regardless, marking it as static will force the issue.
> 
> An optimization that is on similar boundaries as virtual by default. :)

Indeed, though the compiler has a much better chance of determining that a nested function can be made static than determining that a virtual function can be made non-virtual.

- Jonathan M Davis
July 08, 2013
On Sun, Jul 07, 2013 at 01:55:16PM -0700, Jonathan M Davis wrote:
> On Sunday, July 07, 2013 14:30:12 Iain Buclaw wrote:
> > On 6 July 2013 22:41, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > > On Saturday, July 06, 2013 14:13:29 H. S. Teoh wrote:
> > >> Shouldn't the frame pointer be generated only if f() actually tries to access something outside of the definition of T?
> > > 
> > > Probably, but that's arguably an optimization. Regardless, marking it as static will force the issue.
> > 
> > An optimization that is on similar boundaries as virtual by default. :)
> 
> Indeed, though the compiler has a much better chance of determining that a nested function can be made static than determining that a virtual function can be made non-virtual.
[...]

I may be remembering incorrectly, but my impression was that TDPL states that the context pointer is only added where necessary. So having to explicitly state 'static struct' to suppress the context pointer was a bit surprising for me.


T

-- 
It always amuses me that Windows has a Safe Mode during bootup. Does that mean that Windows is normally unsafe?
July 08, 2013
On Monday, July 08, 2013 10:56:31 H. S. Teoh wrote:
> On Sun, Jul 07, 2013 at 01:55:16PM -0700, Jonathan M Davis wrote:
> > On Sunday, July 07, 2013 14:30:12 Iain Buclaw wrote:
> > > On 6 July 2013 22:41, Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > > > On Saturday, July 06, 2013 14:13:29 H. S. Teoh wrote:
> > > >> Shouldn't the frame pointer be generated only if f() actually tries to access something outside of the definition of T?
> > > > 
> > > > Probably, but that's arguably an optimization. Regardless, marking it as static will force the issue.
> > > 
> > > An optimization that is on similar boundaries as virtual by default.
> > > 
> > > :)
> > 
> > Indeed, though the compiler has a much better chance of determining that a nested function can be made static than determining that a virtual function can be made non-virtual.
> 
> [...]
> 
> I may be remembering incorrectly, but my impression was that TDPL states that the context pointer is only added where necessary. So having to explicitly state 'static struct' to suppress the context pointer was a bit surprising for me.

Well, I don't think that there's much question that it would be nicer if the compiler made it static when it could, but it doesn't surprise me that it doesn't manage it. It wouldn't hurt to open a bug report for it though.

- Jonathan M Davis