digitalmars.D.learn - Nasty supprise when using c 'anonymous struct and union' in D with
- Arjan (34/34) Dec 29 2020 see https://en.cppreference.com/w/c/language/struct
- Steven Schveighoffer (9/50) Dec 29 2020 I added in some printouts of the addresses of the variables.
- Arjan (10/21) Dec 29 2020 On the C/C++ side there is no static. I added those on the D side
- H. S. Teoh (7/11) Dec 29 2020 You need to add 'static' to the (outer) struct declarations in your
- Steven Schveighoffer (3/12) Dec 29 2020 Not if the struct is POD. And in this case, they are all POD (no methods...
- H. S. Teoh (6/13) Dec 29 2020 [...]
- Steven Schveighoffer (6/29) Dec 29 2020 structs only add context pointers if nested in functions (and even then,...
- Arjan (5/15) Dec 29 2020 That is what I discovered indeed. Thanks both for answering and
see https://en.cppreference.com/w/c/language/struct It seems the 'static' must NOT be used here to get the equivalent behavior of c, when left in the assertions will fail. Is this expected? ``` unittest { struct W { align(1): long k; long l; } struct V { align(1): union // anonymous union { /*static*/ struct // anonymous structure { long i; long j; } W w; } int m; } V v1; v1.i = 2; assert( 2 == v1.w.k ); v1.w.l = 5; assert( 5 == v1.j ); } ```
Dec 29 2020
On 12/29/20 7:38 AM, Arjan wrote:see https://en.cppreference.com/w/c/language/struct It seems the 'static' must NOT be used here to get the equivalent behavior of c, when left in the assertions will fail. Is this expected? ``` unittest { struct W { align(1): long k; long l; } struct V { align(1): union // anonymous union { /*static*/ struct // anonymous structure { long i; long j; } W w; } int m; } V v1; v1.i = 2; assert( 2 == v1.w.k ); v1.w.l = 5; assert( 5 == v1.j ); } ```I added in some printouts of the addresses of the variables. It appears that if you add static to the struct, it now becomes a static member of the union, which means it's not an instance variable, and is now a thread-local variable. Its address doesn't even coincide remotely with the address of v1. What is the equivalent behavior for C that you are expecting? The usage of "static struct" doesn't appear in that page you linked to. -Steve
Dec 29 2020
On Tuesday, 29 December 2020 at 14:42:07 UTC, Steven Schveighoffer wrote:On 12/29/20 7:38 AM, Arjan wrote:On the C/C++ side there is no static. I added those on the D side to to make sure there is no context pointer being added, since that will change the layout and size of struct. (in the c/c++ code those unions and structs are nested several levels deep) Based on this: https://dlang.org/spec/struct.html#nested I expected to have the equivalent of C behavior in D by using the static keyword, which in this case just caused havoc. So the other way around.see https://en.cppreference.com/w/c/language/structI added in some printouts of the addresses of the variables. It appears that if you add static to the struct, it now becomes a static member of the union, which means it's not an instance variable, and is now a thread-local variable. Its address doesn't even coincide remotely with the address of v1. What is the equivalent behavior for C that you are expecting? The usage of "static struct" doesn't appear in that page you linked to.
Dec 29 2020
On Tue, Dec 29, 2020 at 05:13:19PM +0000, Arjan via Digitalmars-d-learn wrote: [...]On the C/C++ side there is no static. I added those on the D side to to make sure there is no context pointer being added, since that will change the layout and size of struct. (in the c/c++ code those unions and structs are nested several levels deep)You need to add 'static' to the (outer) struct declarations in your unittest block, because otherwise they *will* have a context pointer. This is because unittest blocks are compiled as if they were functions, and struct declarations in a function do acquire context pointers. --T
Dec 29 2020
On 12/29/20 12:45 PM, H. S. Teoh wrote:On Tue, Dec 29, 2020 at 05:13:19PM +0000, Arjan via Digitalmars-d-learn wrote: [...]Not if the struct is POD. And in this case, they are all POD (no methods). -SteveOn the C/C++ side there is no static. I added those on the D side to to make sure there is no context pointer being added, since that will change the layout and size of struct. (in the c/c++ code those unions and structs are nested several levels deep)You need to add 'static' to the (outer) struct declarations in your unittest block, because otherwise they *will* have a context pointer.
Dec 29 2020
On Tue, Dec 29, 2020 at 12:50:06PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:On 12/29/20 12:45 PM, H. S. Teoh wrote:[...][...] Hmm, I didn't know that! I thought they always get a context pointer. Maybe I got confused with nested functions. I stand corrected. --TYou need to add 'static' to the (outer) struct declarations in your unittest block, because otherwise they *will* have a context pointer.Not if the struct is POD. And in this case, they are all POD (no methods).
Dec 29 2020
On 12/29/20 12:13 PM, Arjan wrote:On Tuesday, 29 December 2020 at 14:42:07 UTC, Steven Schveighoffer wrote:structs only add context pointers if nested in functions (and even then, only if it's not POD). If nested in structs, classes, or unions (or anything else), then no context pointer is added. So the answer is, don't use static. -SteveOn 12/29/20 7:38 AM, Arjan wrote:On the C/C++ side there is no static. I added those on the D side to to make sure there is no context pointer being added, since that will change the layout and size of struct. (in the c/c++ code those unions and structs are nested several levels deep) Based on this: https://dlang.org/spec/struct.html#nested I expected to have the equivalent of C behavior in D by using the static keyword, which in this case just caused havoc. So the other way around.see https://en.cppreference.com/w/c/language/structI added in some printouts of the addresses of the variables. It appears that if you add static to the struct, it now becomes a static member of the union, which means it's not an instance variable, and is now a thread-local variable. Its address doesn't even coincide remotely with the address of v1. What is the equivalent behavior for C that you are expecting? The usage of "static struct" doesn't appear in that page you linked to.
Dec 29 2020
On Tuesday, 29 December 2020 at 17:49:20 UTC, Steven Schveighoffer wrote:On 12/29/20 12:13 PM, Arjan wrote:On Tuesday, 29 December 2020 at 14:42:07 UTC, Steven Schveighoffer wrote:On 12/29/20 7:38 AM, Arjan wrote:see https://en.cppreference.com/w/c/language/structstructs only add context pointers if nested in functions (and even then, only if it's not POD). If nested in structs, classes, or unions (or anything else), then no context pointer is added. So the answer is, don't use static.That is what I discovered indeed. Thanks both for answering and the additional information. This could however be made more explicit and clear in the documentation.
Dec 29 2020