union field access and compatible types

N

nicolas.sitbon

Hi all,
My question is simple but I can't find the answer in the standard (C99
TC3).
is this permitted?

union
{
const void * ro;
void * rw;
}
variant;

void * buf = strdup("bla");
/* check allocation success */
variant.rw = buf.
puts(variant.ro);

Thanks by advance.
 
B

Ben Bacarisse

nicolas.sitbon said:
My question is simple but I can't find the answer in the standard (C99
TC3).
is this permitted?

union
{
const void * ro;
void * rw;
}
variant;

void * buf = strdup("bla");
/* check allocation success */
variant.rw = buf.
puts(variant.ro);

Yes. Pointers to const and non-const versions of the same type have
the same alignment and representation (6.2.5 p27). I don't see any
other pitfalls but maybe you were worrying about some other aspect of
the code.

How did this come up? I'd prefer to use a cast if I needed to change
the qualifiers on the target of a pointer. It makes this significant
change so much more apparent in the code so I imagine that this effect
is not the main purpose of this code fragment.
 
N

nicolas.sitbon

Yes.  Pointers to const and non-const versions of the same type have
the same alignment and representation (6.2.5 p27).  I don't see any
other pitfalls but maybe you were worrying about some other aspect of
the code.

How did this come up?  I'd prefer to use a cast if I needed to change
the qualifiers on the target of a pointer.  It makes this significant
change so much more apparent in the code so I imagine that this effect
is not the main purpose of this code fragment.

thanks for your answer, in fact, I don't need to change the
qualifiers, rather I'm looking for a way to create a generic data
structure that can can be used with const generic pointer or non const
generic pointer, preventing the user from casting if I would hard code
the qualifier. Think of a generic linked list where you can put const
data or variable data without casting because I would code void * data
and the user want to put a const char *. I hope it is clear, english
is not my mother tongue.
 
B

Ben Bacarisse

nicolas.sitbon said:
"nicolas.sitbon" <[email protected]> writes:
How did this come up?

It is best to snip sigs unless you are commenting on them.
thanks for your answer, in fact, I don't need to change the
qualifiers, rather I'm looking for a way to create a generic data
structure that can can be used with const generic pointer or non const
generic pointer, preventing the user from casting if I would hard code
the qualifier.

If you hard-code the const, why does the user have to cast?
Think of a generic linked list where you can put const
data or variable data without casting because I would code void * data
and the user want to put a const char *.

As a rule, generic container structures don't know enough about the
data to do anything much with it (they may pass it to a function but
that is about it). That makes me wonder why you need the non-const
data variant.
I hope it is clear, english is not my mother tongue.

Yes, perfectly clear. Your English is excellent. While on the
subject of language, pointers are problematic. You talk about a
"const generic pointer or non const generic pointer" but in fact the
pointer is not const qualified in either case, it is the data pointed
*to* that is marked const. This is not a complaint -- everyone drops
into shorthands like this all the time -- but sometimes it matters and
it pays to be vigilant for those cases where they might be a
misunderstanding.
 
N

nicolas.sitbon

If you hard-code the const, why does the user have to cast?

If I hard-code the const and the user put a non const data, it makes
no problem, but if he wants to get back his data that is now stored in
a pointer to const, he is forced to cast.
As a rule, generic container structures don't know enough about the
data to do anything much with it (they may pass it to a function but
that is about it).  That makes me wonder why you need the non-const
data variant.

see above, when you want to get back your data in a pointer to non
const data, you are forced to cast.
Yes, perfectly clear.  Your English is excellent.  While on the
subject of language, pointers are problematic.  You talk about a
"const generic pointer or non const generic pointer" but in fact the
pointer is not const qualified in either case, it is the data pointed
*to* that is marked const.  This is not a complaint -- everyone drops
into shorthands like this all the time -- but sometimes it matters and
it pays to be vigilant for those cases where they might be a
misunderstanding.
You're right, it's a bad shorthand.
 
B

Ben Bacarisse

nicolas.sitbon said:
If I hard-code the const and the user put a non const data, it makes
no problem, but if he wants to get back his data that is now stored in
a pointer to const, he is forced to cast.

True, but I see that as an advantage. I'd like to see the end result
using your idea before deciding, but I /think/ it will obfuscate when
the data is and is not const. Do you have any working code yet?

<snip>
 
T

Tim Rentsch

nicolas.sitbon said:
Hi all,
My question is simple but I can't find the answer in the standard (C99
TC3).
is this permitted?

union
{
const void * ro;
void * rw;
}
variant;

void * buf = strdup("bla");
/* check allocation success */
variant.rw = buf.
puts(variant.ro);

The short answer is yes. The two members involved have types
that are guaranteed to have the same representation and alignment
requirements. This is covered in section 6.2.5 paragraph 27.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top