digitalmars.D.learn - Wrong pointer calculation without casting on struct
- tcak (20/20) Feb 05 2015 I am on 64-bit Linux.
- tcak (9/29) Feb 05 2015 By the way,
- Baz (25/63) Feb 05 2015 I've tried this;
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (8/10) Feb 05 2015 In pointer arithmetic, the increment value means "that many *objects*
I am on 64-bit Linux. I defined a struct that it 8 bytes in total. align(1) struct MessageBase{ align(1): ushort qc; ushort wc; ushort id; ushort contentLength; void[0] content; } I defined a function in this struct that tries to set a pointer to "contentLength" field. writeln( "Without: ", (&this + id.offsetof) ); writeln( "With : ", (cast(size_t)&this + id.offsetof) ); Results: Without: 7FFFF74F5030 With : 140737342558228 0x7FFFF74F5030 => 140737342558256 As it is seen, there is 28 bytes of difference between them. What is this behaviour exactly?
Feb 05 2015
On Friday, 6 February 2015 at 03:59:51 UTC, tcak wrote:I am on 64-bit Linux. I defined a struct that it 8 bytes in total. align(1) struct MessageBase{ align(1): ushort qc; ushort wc; ushort id; ushort contentLength; void[0] content; } I defined a function in this struct that tries to set a pointer to "contentLength" field. writeln( "Without: ", (&this + id.offsetof) ); writeln( "With : ", (cast(size_t)&this + id.offsetof) ); Results: Without: 7FFFF74F5030 With : 140737342558228 0x7FFFF74F5030 => 140737342558256 As it is seen, there is 28 bytes of difference between them. What is this behaviour exactly?By the way, writeln("Base Normal: ", &this); writeln("Base Cast : ", cast(size_t)&this); Result: Base Normal: 7FFFF74F5010 Base Cast : 140737342558224 0x7FFFF74F5010 => 140737342558224 These are same. So, the issue is about addition process.
Feb 05 2015
On Friday, 6 February 2015 at 04:10:08 UTC, tcak wrote:On Friday, 6 February 2015 at 03:59:51 UTC, tcak wrote:I've tried this; import std.stdio; struct MessageBase{ align(1): ushort qc; ushort wc; ushort id; ushort contentLength; void[0] content; void a(){ writefln("%.8X",(cast(void*)&this + id.offsetof)); writefln("%.8X",(cast(size_t)&this + id.offsetof)); } } void main() { MessageBase mb; mb.a; } and got the same value for both. Your problem is: typeof(&this).stringof is "MessageBase*" so with ptr arithmetic when you add 1 you actually shift by 1 * MessageBase.sizeof. typeof(cast(void*)&this) is "void*" so with ptr arithmetic you shift by a certain number of bytes.I am on 64-bit Linux. I defined a struct that it 8 bytes in total. align(1) struct MessageBase{ align(1): ushort qc; ushort wc; ushort id; ushort contentLength; void[0] content; } I defined a function in this struct that tries to set a pointer to "contentLength" field. writeln( "Without: ", (&this + id.offsetof) ); writeln( "With : ", (cast(size_t)&this + id.offsetof) ); Results: Without: 7FFFF74F5030 With : 140737342558228 0x7FFFF74F5030 => 140737342558256 As it is seen, there is 28 bytes of difference between them. What is this behaviour exactly?By the way, writeln("Base Normal: ", &this); writeln("Base Cast : ", cast(size_t)&this); Result: Base Normal: 7FFFF74F5010 Base Cast : 140737342558224 0x7FFFF74F5010 => 140737342558224 These are same. So, the issue is about addition process.
Feb 05 2015
On 02/05/2015 07:59 PM, tcak wrote:writeln( "Without: ", (&this + id.offsetof) );In pointer arithmetic, the increment value means "that many *objects* away", not "than many bytes away". Since id.offsetof is 4, you are calculating 4 MessageBase objects away (4*8==32 bytes away).writeln( "With : ", (cast(size_t)&this + id.offsetof) );That is not pointer arithmetic, so the increment is just 4. 32 - 4 == 28. Ali
Feb 05 2015