Discussion:
Regarding union initialization
(too old to reply)
Melzzzzz
2017-05-13 21:44:27 UTC
Permalink
Raw Message
Today I stumbled across one quirk regarding union initialization.

struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};

Code wasw like this:
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;

What a surprise. Fields were not initialized ;p
I added printf to fields and voila fields are initializes ;)
gcc seems to disregard this if fields are not used in function.
So I made this change:
p->c= (struct Other){v1,v2};
and voila it now works ;)
Am I stumbled on UB or something or is this bug in gcc?
--
press any key to continue or any other to quit...
Ben Bacarisse
2017-05-13 23:18:41 UTC
Permalink
Raw Message
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
What a surprise. Fields were not initialized ;p
Do you mean that p->c.com.a and p->c.con.b do not get the value you
expect after the assignment (it's not, technically, an initialisation)?

By the way, c, a, b and so on are called members, not fields.
Post by Melzzzzz
I added printf to fields and voila fields are initializes ;)
Are you looking at the assembler output? A compiler is allowed to
ignore code if the results are no used, so adding a printf call may well
change the generated code.
Post by Melzzzzz
gcc seems to disregard this if fields are not used in function.
p->c= (struct Other){v1,v2};
and voila it now works ;)
Am I stumbled on UB or something or is this bug in gcc?
Can you post some runable code that shows what you are surprised by?
--
Ben.
Melzzzzz
2017-05-13 23:28:49 UTC
Permalink
Raw Message
Post by Ben Bacarisse
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
What a surprise. Fields were not initialized ;p
Do you mean that p->c.com.a and p->c.con.b do not get the value you
expect after the assignment (it's not, technically, an initialisation)?
By the way, c, a, b and so on are called members, not fields.
Post by Melzzzzz
I added printf to fields and voila fields are initializes ;)
Are you looking at the assembler output? A compiler is allowed to
ignore code if the results are no used, so adding a printf call may well
change the generated code.
Post by Melzzzzz
gcc seems to disregard this if fields are not used in function.
p->c= (struct Other){v1,v2};
and voila it now works ;)
Am I stumbled on UB or something or is this bug in gcc?
Can you post some runable code that shows what you are surprised by?
Actually I hacked Idris compiler (rts) and got surprised by that ;)
--
press any key to continue or any other to quit...
bartc
2017-05-13 23:37:33 UTC
Permalink
Raw Message
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
This doesn't make sense. Does 'struct Other' also contain fields a and b?
Post by Melzzzzz
What a surprise. Fields were not initialized ;p
I added printf to fields and voila fields are initializes ;)
How did you know they weren't initialised without the printf?
Post by Melzzzzz
gcc seems to disregard this if fields are not used in function.
If looking at generated code, turn off optimisation. Or use a less
complicated compiled that is more likely to do exactly what you tell it.
--
bartc
Melzzzzz
2017-05-13 23:57:45 UTC
Permalink
Raw Message
Post by bartc
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
This doesn't make sense. Does 'struct Other' also contain fields a and b?
Post by Melzzzzz
What a surprise. Fields were not initialized ;p
I added printf to fields and voila fields are initializes ;)
How did you know they weren't initialised without the printf?
I got segfault as fields were tag and arity.
Post by bartc
Post by Melzzzzz
gcc seems to disregard this if fields are not used in function.
If looking at generated code, turn off optimisation. Or use a less
complicated compiled that is more likely to do exactly what you tell it.
Heh, problem is that gcc is used mostly ;)
--
press any key to continue or any other to quit...
James Kuyper
2017-05-14 01:36:16 UTC
Permalink
Raw Message
Post by Melzzzzz
Post by bartc
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
This doesn't make sense. Does 'struct Other' also contain fields a and b?
Post by Melzzzzz
What a surprise. Fields were not initialized ;p
I added printf to fields and voila fields are initializes ;)
How did you know they weren't initialised without the printf?
I got segfault as fields were tag and arity.
If the observable behavior of your code never depends upon the value
stored in p->c.con.a or p->c.con.b, a fully conforming implementation of
C need not actually bother storing those values there. That could be why
adding the printf() makes the difference.

However, a segfault should only occur as result of writing code with
undefined behavior. The code you've shown so far provides no excuse, in
itself, for a segfault. However, the problematic code might reside in
some other part of your program. Could you show us a small but complete
and compilable program demonstrating this problem?
Melzzzzz
2017-05-14 05:59:07 UTC
Permalink
Raw Message
Post by James Kuyper
Post by Melzzzzz
Post by bartc
Post by Melzzzzz
Today I stumbled across one quirk regarding union initialization.
struct Something{
union {
struct Other con;
int a;
float b;
/* ....*/
}c;
};
struct Something* p = malloc(size);
p->c.con.a = v1;
p->c.con.b = v2;
This doesn't make sense. Does 'struct Other' also contain fields a and b?
Post by Melzzzzz
What a surprise. Fields were not initialized ;p
I added printf to fields and voila fields are initializes ;)
How did you know they weren't initialised without the printf?
I got segfault as fields were tag and arity.
If the observable behavior of your code never depends upon the value
stored in p->c.con.a or p->c.con.b, a fully conforming implementation of
C need not actually bother storing those values there. That could be why
adding the printf() makes the difference.
However, a segfault should only occur as result of writing code with
undefined behavior. The code you've shown so far provides no excuse, in
itself, for a segfault. However, the problematic code might reside in
some other part of your program. Could you show us a small but complete
and compilable program demonstrating this problem?
Aaaaaaaaaah. I now know now what was the problem ;)
That function is actually macro so I forgot to recompile packages that
used it ;)
Silly me ;)
--
press any key to continue or any other to quit...
Loading...