www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - -release compiler switch and associative arrays

reply Graham Cole <grahamc001uk yahoo.co.uk> writes:
I understand from the documentation that the "-release" compiler switch tur=
ns off "array bounds checking for system and trusted functions".=0A=0AIs it=
 correct that the following code should seg fault when compiled with "-rele=
ase" ?=0A=0Astring[string] h;=0Ah["abc"] =3D "def";=0Astring s =3D h["aaa"]=
;=0A=0AI.e. retrieving from an associative array for a non existent key.=0A=
=0AI would have thought that an exception should be generated in this case =
when compiled with=0A"-release" (as it is when compiled without).=0A=0AThis=
 code behaves the same when compiled by both D1 and D2.=0A=0AShould I repor=
t this as a bug ?=0A
Oct 09 2011
next sibling parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
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
Oct 09 2011
prev sibling next sibling parent reply Vijay Nayar <madric gmail.com> writes:
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
Oct 11 2011
parent Kagamin <spam here.lot> writes:
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.
Oct 11 2011
prev sibling next sibling parent Vijay Nayar <madric gmail.com> writes:
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
Oct 11 2011
prev sibling parent Don <nospam nospam.com> writes:
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"];
Oct 11 2011