Thread overview | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 05, 2013 [Issue 10763] New: (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=10763 Summary: (&x)[0 .. 1] doesn't work in CTFE Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Keywords: CTFE Severity: enhancement Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: nilsbossung@googlemail.com --- Comment #0 from Nils <nilsbossung@googlemail.com> 2013-08-05 15:42:46 PDT --- static assert({ int x; int[] a = (&x)[0 .. 1]; return true; }()); Error: pointer & x cannot be sliced at compile time (it does not point to an array) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 12, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #1 from Don <clugdbug@yahoo.com.au> 2013-08-12 14:16:59 PDT --- This restriction is intentional. It's a consequence of strictly enforcing C's pointer arithmetic rules. You can only slice a pointer that you can perform pointer arithmetic on. Where x is a variable, C does not guarantee that &x + 1 is a legal address. (For example, it might be 0, if x is at the end of the address space). (Enforcing C's pointer arithmetic enormously simplifies the implementation. Allowing this would create a huge number of special cases). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 12, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 timon.gehr@gmx.ch changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |timon.gehr@gmx.ch --- Comment #2 from timon.gehr@gmx.ch 2013-08-12 14:59:00 PDT --- What kind of special cases? (The above code works in my own implementation.) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 13, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #3 from Don <clugdbug@yahoo.com.au> 2013-08-12 17:13:15 PDT --- It's basically the same as issue 10266. The corner cases arise if you still disallow &x + 1. My guess is that you're allowing it in your implementation? The problem with allowing it is that we're departing from C. And there's annoying things like: // global scope int x; int *p = &x + 1; // points to junk! - must not compile Is there really a use case for this unsafe behaviour? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 13, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #4 from timon.gehr@gmx.ch 2013-08-12 19:01:50 PDT --- (In reply to comment #3) > It's basically the same as issue 10266. Issue 10266 additionally requests allowing reinterpret-casts between T* and T[1]* (my implementation currently rejects this, but allowing it would be easy.) > The corner cases arise if you still disallow &x + 1. My guess is that you're > allowing it in your implementation? > ... Yes, but dereferencing it is an error. Subtracting one results in the address of x. > The problem with allowing it is that we're departing from C. Does C actually disallow adding 0 to a pointer to a local variable? That's what the example is doing. Furthermore, I don't see what the restriction buys in terms of implementation effort. Every program can be rewritten to only contain arrays. > And there's annoying things like: > > // global scope > int x; > int *p = &x + 1; // points to junk! - must not compile > Agreed, but I think this is not closely related. DMD already allows creating invalid addresses in CTFE by other means. > > Is there really a use case for this unsafe behaviour? Make more code CTFE-able. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 19, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #5 from Don <clugdbug@yahoo.com.au> 2013-08-19 02:37:33 PDT --- (In reply to comment #4) > (In reply to comment #3) > > It's basically the same as issue 10266. > > Issue 10266 additionally requests allowing reinterpret-casts between T* and T[1]* (my implementation currently rejects this, but allowing it would be easy.) > > > The corner cases arise if you still disallow &x + 1. My guess is that you're > > allowing it in your implementation? > > ... > > Yes, but dereferencing it is an error. Subtracting one results in the address of x. That is not the issue. The problem is that in C, simply creating the pointer is undefined behaviour. No dereferencing is involved. Note that is undefined behaviour, it's not even implementation-specific behaviour! Simply storing an invalid pointer into a pointer register may generate a hardware exception on some systems. In C, you are not permitted to do pointer arithmetic unless the pointer points to an array, or one-past-the-end-of-an-array. > > The problem with allowing it is that we're departing from C. > > Does C actually disallow adding 0 to a pointer to a local variable? That's what the example is doing. I'm not sure if that's legal or not. I suspect not, though I think it would always work in practice. But adding 1 to a pointer to a local variable is definitely illegal, and there are systems where it will not work. So the end of the slice is problematic. > > Is there really a use case for this unsafe behaviour? > > Make more code CTFE-able. But it's undefined behaviour. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 19, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #6 from timon.gehr@gmx.ch 2013-08-19 03:25:14 PDT --- (In reply to comment #5) > (In reply to comment #4) > > (In reply to comment #3) > > ... > > > The corner cases arise if you still disallow &x + 1. My guess is that you're > > > allowing it in your implementation? > > > ... > > > > Yes, but dereferencing it is an error. Subtracting one results in the address of x. > > That is not the issue. The problem is that in C, simply creating the pointer is undefined behaviour. I guess I'll update my implementation eventually to disallow this. (Other related limitations are that it currently allows escaping addresses to locals and simply closes over them, array appends may cause non-determinism and pointers can be freely compared.) > ... > > > Is there really a use case for this unsafe behaviour? > > > > Make more code CTFE-able. > > But it's undefined behaviour. There is not really a reason why (&x)[0..1] should be UB. But I guess if you want to keep C behaviour and also keep the invariant that slices always point to arrays, this is indeed not fixable. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 19, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 Iain Buclaw <ibuclaw@ubuntu.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |ibuclaw@ubuntu.com --- Comment #7 from Iain Buclaw <ibuclaw@ubuntu.com> 2013-08-19 03:42:54 PDT --- (In reply to comment #3) > It's basically the same as issue 10266. > The corner cases arise if you still disallow &x + 1. My guess is that you're > allowing it in your implementation? > > The problem with allowing it is that we're departing from C. And there's annoying things like: > > // global scope > int x; > int *p = &x + 1; // points to junk! - must not compile > > > Is there really a use case for this unsafe behaviour? Only one would be in std.math if we want to make the elementary functions CTFE-able (we've discussed this before). But yes, I think that it is right to disallow it, as there is no clean way to slice up basic types into an array and guarantee ie: format or endian correctness at compile time (cross-compilers, for instance). -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 19, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #8 from Don <clugdbug@yahoo.com.au> 2013-08-19 04:48:39 PDT --- (In reply to comment #7) > (In reply to comment #3) > > It's basically the same as issue 10266. > > The corner cases arise if you still disallow &x + 1. My guess is that you're > > allowing it in your implementation? > > > > The problem with allowing it is that we're departing from C. And there's annoying things like: > > > > // global scope > > int x; > > int *p = &x + 1; // points to junk! - must not compile > > > > > > Is there really a use case for this unsafe behaviour? > > Only one would be in std.math if we want to make the elementary functions CTFE-able (we've discussed this before). That's why my proposed solution for that is to allow only the complete expression, where the pointer is instantly dereferenced: (cast(ulong *)cast(void *)&f)[0]; and it really only needs to be allowed for 80-bit reals, since casting float<->int and double<->long is already supported. The minimal operations are: - significand <-> ulong - sign + exponent <-> ushort That would give us four special-case hacks which are x87 specific. Effectively they are intrinsics with ugly syntax. The existing code could be modified slightly to only use those four operations, with no performance penalty. > But yes, I think that it is right to disallow it, as there is no clean way to slice up basic types into an array and guarantee ie: format or endian correctness at compile time (cross-compilers, for instance). It's an ugly area. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
August 19, 2013 [Issue 10763] (&x)[0 .. 1] doesn't work in CTFE | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nils | http://d.puremagic.com/issues/show_bug.cgi?id=10763 --- Comment #9 from Iain Buclaw <ibuclaw@ubuntu.com> 2013-08-19 05:29:09 PDT --- (In reply to comment #8) > (In reply to comment #7) > > (In reply to comment #3) > > > It's basically the same as issue 10266. > > > The corner cases arise if you still disallow &x + 1. My guess is that you're > > > allowing it in your implementation? > > > > > > The problem with allowing it is that we're departing from C. And there's annoying things like: > > > > > > // global scope > > > int x; > > > int *p = &x + 1; // points to junk! - must not compile > > > > > > > > > Is there really a use case for this unsafe behaviour? > > > > Only one would be in std.math if we want to make the elementary functions CTFE-able (we've discussed this before). > > That's why my proposed solution for that is to allow only the complete expression, where the pointer is instantly dereferenced: > > (cast(ulong *)cast(void *)&f)[0]; > > and it really only needs to be allowed for 80-bit reals, since casting float<->int and double<->long is already supported. > And (speaking as someone who stubbed out your implementation of float<->int and double<->long cast) the only reason why it's supported is because the backend I implement against can (thankfully) do re-interpreted native casts between basic types such as integer, float, complex and vectors. You will need to support all reals that have support in std.math. This includes 64-bit, 80-bit, 96-bit (really just 80-bit), 128-bit (likewise), and 128-bit (quadruple). There are only three supported formats really... (double-double will have to keep with partial support for the time being, sorry PPC!) > The minimal operations are: > - significand <-> ulong > - sign + exponent <-> ushort > > That would give us four special-case hacks which are x87 specific. Effectively they are intrinsics with ugly syntax. > I veto any new addition that is x87 specific - or, more accurately endian specific. Remember its: version(BigEndian) short sign_exp = (cast(ushort*)&x)[0]; else short sign_exp = (cast(ushort*)&x)[5]; -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation