Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
October 09, 2011 -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
I understand from the documentation that the "-release" compiler switch turns off "array bounds checking for system and trusted functions". Is it correct that the following code should seg fault when compiled with "-release" ? string[string] h; h["abc"] = "def"; string s = h["aaa"]; I.e. retrieving from an associative array for a non existent key. I would have thought that an exception should be generated in this case when compiled with "-release" (as it is when compiled without). This code behaves the same when compiled by both D1 and D2. Should I report this as a bug ? |
October 09, 2011 Re: -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Graham Cole | On 09-10-2011 13:24, Graham Cole wrote:
> I understand from the documentation that the "-release" compiler switch turns off "array bounds checking for system and trusted functions".
>
> Is it correct that the following code should seg fault when compiled with "-release" ?
>
> string[string] h;
> h["abc"] = "def";
> string s = h["aaa"];
>
> I.e. retrieving from an associative array for a non existent key.
>
> I would have thought that an exception should be generated in this case when compiled with
> "-release" (as it is when compiled without).
>
> This code behaves the same when compiled by both D1 and D2.
>
> Should I report this as a bug ?
>
To generate a sensible exception in the first place, you'd have to actually *do* bounds checking. When you disable bounds checking, you're just allowing it to read/write beyond the bounds of the array, which any sane OS won't be too happy with. :)
- Alex
|
October 11, 2011 Re: -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Graham Cole | On Sun, 09 Oct 2011 12:24:24 +0100, Graham Cole wrote: > I understand from the documentation that the "-release" compiler switch turns off "array bounds checking for system and trusted functions". > > Is it correct that the following code should seg fault when compiled with "-release" ? > > string[string] h; > h["abc"] = "def"; > string s = h["aaa"]; > > I.e. retrieving from an associative array for a non existent key. > > I would have thought that an exception should be generated in this case when compiled with "-release" (as it is when compiled without). > > This code behaves the same when compiled by both D1 and D2. > > Should I report this as a bug ? Howdy Mr. Cole, The "-release" flag disables runtime checks of data ranges and bounds of things like arrays and pointers. These checks take a little bit of time, but they help you catch an error as early as possible. Without the "-release" flag, the checks are removed, so there are two possibilities when you index an array index. A. The memory address is out of bounds for the program as a whole, and results in a segfault. B. The memory address is in range for the the program as a whole, but has no been initialized or refers to data in a completely different variable. Errors of the second type are especially sinister and very hard to debug. Consider the following program: void main() { int[] ages = [28, 23, 40]; assert(ages[0] == 28); ages[3] = 54; assert(ages[3] == 54); } $ dmd -release bounds.d $ ./bounds # No segfault because the address is within the address space # for the program allowed by the OS. $ dmd bounds.d $ ./bounds core.exception.RangeError@bounds(6): Range violation ---------------- ./bounds(onRangeError+0x28) [0x805f908] ./bounds(_d_array_bounds+0x16) [0x805d516] ./bounds() [0x805ae8e] ./bounds(_Dmain+0x6c) [0x805ae40] ./bounds(_D2rt6dmain24mainUiPPaZi7runMainMFZv+0x1a) [0x805d96e] ./bounds(_D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv+0x20) [0x805d608] ./bounds(_D2rt6dmain24mainUiPPaZi6runAllMFZv+0x32) [0x805d9b2] ./bounds(_D2rt6dmain24mainUiPPaZi7tryExecMFMDFZvZv+0x20) [0x805d608] ./bounds(main+0x94) [0x805d5b4] /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7) [0xb7681e37] ./bounds() [0x805ad21] ---------------- - Vijay |
October 11, 2011 Re: -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vijay Nayar | On Tue, 11 Oct 2011 14:45:38 +0000, Vijay Nayar wrote: > On Sun, 09 Oct 2011 12:24:24 +0100, Graham Cole wrote: > >> I understand from the documentation that the "-release" compiler switch turns off "array bounds checking for system and trusted functions". >> >> Is it correct that the following code should seg fault when compiled with "-release" ? >> >> string[string] h; >> h["abc"] = "def"; >> string s = h["aaa"]; >> >> I.e. retrieving from an associative array for a non existent key. >> >> I would have thought that an exception should be generated in this case when compiled with "-release" (as it is when compiled without). >> >> This code behaves the same when compiled by both D1 and D2. >> >> Should I report this as a bug ? Oh, if your question is specifically about associative arrays, like string [string], then the reason why there is no out-of-bounds problem is that D associative arrays are sparsely populated and support insertion. http://www.digitalmars.com/d/2.0/arrays.html#associative - Vijay |
October 11, 2011 Re: -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Graham Cole | On 09.10.2011 13:24, Graham Cole wrote:
> I understand from the documentation that the "-release" compiler switch turns off "array bounds checking for system and trusted functions".
>
> Is it correct that the following code should seg fault when compiled with "-release" ?
>
> string[string] h;
> h["abc"] = "def";
> string s = h["aaa"];
>
> I.e. retrieving from an associative array for a non existent key.
>
> I would have thought that an exception should be generated in this case when compiled with
> "-release" (as it is when compiled without).
>
> This code behaves the same when compiled by both D1 and D2.
>
> Should I report this as a bug ?
In the compiler source (e2ir.c, IndexExp::toElem), AA checking is generated only when bounds checking is enabled. So it's intentional.
What really happens is that h[xxx] returns a pointer to the element, or null if none.
If it's null, then a bounds error is thrown. But this check is removed for -release.
Then string s= h["aaa"] dereferences the null pointer, and you get a segfault.
Here's a funny side-effect: the code below works fine with -release. p is null. But you get an array bounds error if not using -release.
string[string] h;
h["abc"] = "def";
string *p = &h["aaa"];
|
October 12, 2011 Re: -release compiler switch and associative arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vijay Nayar | Vijay Nayar Wrote:
> void main() {
> int[] ages = [28, 23, 40];
> assert(ages[0] == 28);
> ages[3] = 54;
> assert(ages[3] == 54);
> }
>
> $ dmd -release bounds.d
> $ ./bounds
> # No segfault because the address is within the address space
> # for the program allowed by the OS.
Walter said this feature was removed and now you need -no-bounds-check switch to turn checks off in release mode.
|
Copyright © 1999-2021 by the D Language Foundation