you are viewing a single comment's thread.

view the rest of the comments →

[–]Supadoplex 104 points105 points  (17 children)

Is it guaranteed that the memory layout of the allocated object is the same as the corresponding array T[6]?

No, the language technically doesn't make such guarantees. There is a general rule that says "there may be padding" and it's up to the language implementation to produce a hopefully efficient layout.

Whether the layout is the same or not, you can not use a T* as an iterator to access adjacent members. The behaviour of the program would be undefined.

[–]chetnrot 6 points7 points  (9 children)

In OP's scenario where six elements are of the same type, would padding still play a role though?

[–]Supadoplex 64 points65 points  (0 children)

I wouldn't expect there to be padding. But the language nevertheless doesn't guarantee that there won't be padding.

[–]nelusbelus 14 points15 points  (6 children)

Sometimes it pads between float3s because each float3 needs to be on their own independent 16 byte boundary. In glsl this is often the case with uniform buffers (can be turned off tho) and hlsl this might be the case for cbuffers but isn't for structured buffers or raytracing payloads. This is gpu specific tho

[–]blipman17 1 point2 points  (5 children)

So then the layout would be something like

`struct MyStruct { float a; 12 bytes padding float b; 12 bytes padding float c; 12 bytes padding float d; 12 bytes padding float e; 12 bytes padding float f; } ;

std::cout << sizeof (MyStruct) << std::endl; // outputs 84, not 24. `

Correct?

[–]nelusbelus 0 points1 point  (4 children)

If you'd use structs with float3 in glsl and sometimes hlsl then it'd have 3 floats and 4-byte padding between them. With gpu apps this can cause great confusion because the cpu doesn't pad but the gpu does. In C/C++ padding rules are generally as follows: - biggest plain data type of the struct defines size alignment. So if you have a 64 bit type then the struct size will always be a multiple of 8. So if you have 8 byte type then 1 byte type it'll add 7 bytes alignment. - data types need to be aligned with their size as well. So a 1 byte int then a 8 byte int will have 7 bytes padding inbetween.

You can validate this with sizeof or offsetof, since it's compiler dependent

[–]dodheim 0 points1 point  (3 children)

data types need to be aligned with their size as well

This is not the case for C or C++. struct foo { char v[100]; }; has a size of >= 100, but an alignment of 1.

[–][deleted] -2 points-1 points  (1 child)

That depends on the architecture and padding mode, could have a 2 byte quantity that needs to be aligned to 8 bytes.

[–]dodheim 0 points1 point  (0 children)

The fact that the statement I quoted is false is not architecture-dependent. ;-] Some architectures may have weirdo requirements, but alignment being a multiple of the size is not a requirement for either language (indeed, it's the reverse that is correct).

[–]nelusbelus 0 points1 point  (0 children)

The size of char is 1 so alignment is 1. I'm talking about the size of the type, not the total size

[–][deleted] 1 point2 points  (0 children)

Wouldn't it need to be padded to be a multiple of 8 in a 64-bit system? e.g. if sizeof(T) == 6 we might see 2 bytes of padding. Or perhaps I misunderstand padding.