digitalmars.D.learn - ubyte array changing values between calls? Possible bug?
- Gary Willoughby (37/37) Dec 13 2013 I have the following code which is massively simplified from a
- John Colvin (4/42) Dec 13 2013 opAssign is escaping a reference to its stack by assigning the
- =?UTF-8?B?UsOpbXkgTW91w6t6YQ==?= (7/57) Dec 13 2013 It works fine when using dup to the value returned by nativeToBigEndian:
- John Colvin (2/9) Dec 14 2013 As expected, as dup allocates a new array on the heap.
- Gary Willoughby (4/56) Dec 14 2013 I'm not going to lie that has gone over my head a little. Could
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/24) Dec 14 2013 According to documentation, nativeToBigEndian returns a static array
- Gary Willoughby (2/32) Dec 15 2013 Ah right, that now makes perfect sense. Thanks all! :)
I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.d
Dec 13 2013
On Friday, 13 December 2013 at 16:37:51 UTC, Gary Willoughby wrote:I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.dopAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.
Dec 13 2013
It works fine when using dup to the value returned by nativeToBigEndian: public void opAssign(uint value) { this._octets = value.nativeToBigEndian().dup; assert(this._octets == cast (ubyte[]) [1, 2, 3, 4]); } On 12/13/2013 06:35 PM, John Colvin wrote:On Friday, 13 December 2013 at 16:37:51 UTC, Gary Willoughby wrote:I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.dopAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.
Dec 13 2013
On Friday, 13 December 2013 at 18:01:53 UTC, Rémy Mouëza wrote:It works fine when using dup to the value returned by nativeToBigEndian: public void opAssign(uint value) { this._octets = value.nativeToBigEndian().dup; assert(this._octets == cast (ubyte[]) [1, 2, 3, 4]); }As expected, as dup allocates a new array on the heap.
Dec 14 2013
On Friday, 13 December 2013 at 17:35:27 UTC, John Colvin wrote:On Friday, 13 December 2013 at 16:37:51 UTC, Gary Willoughby wrote:I'm not going to lie that has gone over my head a little. Could you explain it more simply please? I just want to totally understand the issue here. Thanks.I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.dopAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.
Dec 14 2013
On 12/14/2013 10:48 AM, Gary Willoughby wrote:On Friday, 13 December 2013 at 17:35:27 UTC, John Colvin wrote:public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } }According to documentation, nativeToBigEndian returns a static array (fixed-length array): It says "returns it as a ubyte[n] where n is the size of the given type." Since static arrays normally live on the stack, the returned array is a local array. As with any slice assignment, the assignment to this._octets in opAssign makes _octets a slice to the elements of that local array. Upon leaving opAssign that array is no more. So, _octets is left referring to elements that are long gone. :( AliopAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.I'm not going to lie that has gone over my head a little. Could you explain it more simply please? I just want to totally understand the issue here. Thanks.
Dec 14 2013
On Sunday, 15 December 2013 at 00:21:37 UTC, Ali Çehreli wrote:On 12/14/2013 10:48 AM, Gary Willoughby wrote:Ah right, that now makes perfect sense. Thanks all! :)On Friday, 13 December 2013 at 17:35:27 UTC, John Colvinwrote:public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } }the staticopAssign is escaping a reference to its stack by assigningCould youarray to the slice _octets. Therefore, garbage.I'm not going to lie that has gone over my head a little.explain it more simply please? I just want to totallyunderstand theissue here. Thanks.According to documentation, nativeToBigEndian returns a static array (fixed-length array): It says "returns it as a ubyte[n] where n is the size of the given type." Since static arrays normally live on the stack, the returned array is a local array. As with any slice assignment, the assignment to this._octets in opAssign makes _octets a slice to the elements of that local array. Upon leaving opAssign that array is no more. So, _octets is left referring to elements that are long gone. :( Ali
Dec 15 2013