473,320 Members | 1,870 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Unions, storage, ABI's

Hi!

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use?

And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I'm not sure)

And another point: if you use the same union across different ABI's,
will that work without problems? For example: if you get a pointer to
such a union from a library compiled by a specific compiler, and then
use it in another module compiled with a different compiler, will
aUnion.Char work as expected?

Someone on the comp.std.c group found this:
C99 6.7.2.1p14 says:

The size of a union is sufficient to contain the largest of its
members. The value of at most one of the members can be stored in
a union object at any time. A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.


That doesn't seem to guarantee much does it?
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed
to work across different ABI's:

MyUnion_t theUnion;
somelib->getUnion(&theUnion);

where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?

Koen
Nov 14 '05 #1
10 1778
Koen wrote:

Hi!

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use?
&aUnion.Double and &aUnion.Char are equal.

And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I'm not sure)


You're right; you're not.
Nov 14 '05 #2
"Koen" <no@ssppaamm.com> writes:
Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use? [...]
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed
to work across different ABI's:

MyUnion_t theUnion;
somelib->getUnion(&theUnion);

where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?


Of course you can use (*ptr).Char or (*ptr).Double to refer to the
corresponding members (or, more idiomatically, ptr->Char or
ptr->Double). Casting would be neither necessary nor useful, since
the expression is already of the correct type. If theUnion contains
valid data, you can access it; if it doesn't, casting won't help.

There's no guarantee that code generated by different compilers will
use the same layout for unions, structs, or anything else. But if the
compilers are on the same system, and you can link code generated by
them into a single executable, the compiler vendors will almost
certainly have made some effort to make their layouts compatible.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #3
Koen <no@ssppaamm.com> wrote:
Does anyone know what the standard says about the way unions are
stored in C? I mean the following: Let's say you have a union with a double and a char field: union MyUnion_t
{
double Double;
char Char;
}; MyUnion_t aUnion;
You need

union MyUnion_t aUnion;

here since MyUnion_T isn't typdefed but just a tag...
Is it standardized somehow which byte of the allocated storage the
Char field will use?
What you cited later, i.e.
... A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.


tells that both the 'Double' and 'Char' members will be at the very
first address of the union. I.e.

&AUninon.Double == (double *) &AUnion
&AUninon.Char == (char * ) &AUnion

That's what is meant by that sentence, i.e. you can use &AUnion after
suitable casting either as a pointer to the 'Double' or to the 'Char'
member (if doing so makes much sense is a different question).
And a related question: if you dump unions in binary form to a file,
and then reload them from the file on a different platform, or with a
program compiled by a different compiler, are you guaranteed to get
back what you stored? (I think not, but I'm not sure)
On a different platform this will definitely not be guaranteed to
work - the floating point format can be completely different (already
sizeof(double) may differ) and also the number of bits in a char could
be different (i.e. the value of CHAR_BIT from limits.h>) as well as
the encoding. Even when compiled with a different compiler you could
theoretically get in trouble if the use different numbers of bits to
store floating point numbers, but I would guess that this is an extre-
mely unlikely case.
And another point: if you use the same union across different ABI's,
will that work without problems? For example: if you get a pointer to
such a union from a library compiled by a specific compiler, and then
use it in another module compiled with a different compiler, will
aUnion.Char work as expected?
As a rule I would expect it to work since a lot of things might break
if different compilers use different chars or doubles (you probably
wouldn't be able to link at all in that case since the libraries would
need t use a different libc). But I don't think there's a promise in
the standard that it will always work.
Someone on the comp.std.c group found this:
a union object at any time. A pointer to a union object, suitably
converted, points to each of its members (or if a member is a bit-
field, then to the unit in which it resides), and vice versa.
That doesn't seem to guarantee much does it?
I was hoping to use (*ptr).Char or (*ptr).Double without having to cast
anything. Looks like no more details are specified about whether this is
supposed to work across different ABI's:
No, you don't need a cast. The sentence just says that you can use the
address of the union after suitable conversion as a pointer to each
of its members, which guarantees that each member lays at the start
of the structure. But there's nothing wrong with using 'ptr->Char' or
'ptr->Double' without the cast - by specifying the member you already
tell the compiler which type is meant. So 'ptr->Char' is a char and
'ptr->Double' a double without any casts.
MyUnion_t theUnion;
somelib->getUnion(&theUnion); where this is in my own program, and somelib is a function table into a
library possibly compiled by another compiler.
Will the libary return a union with the same binary layout as my own
program would do?


As I wrote above, it's very likely to work, but I don't see that there's
a guarantee. But if it doesn't work I would expect things to fail at the
linking stage since such differences would rather likely lead to a lot of
trouble all over the place.
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #4
Koen wrote:

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;


Nobody seems to have pointed out that this declaration is wrong.
There is no type MyUnion_t known. Only "union MyUnion_t" is a
valid type. This is why some people would rather declare the type
in a typedef:

typedef unsion MyUnion_t {
double Double;
char Char;
} MyUnion_t;

Same for structures.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #5
CBFalconer <cb********@yahoo.com> writes:
Koen wrote:

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;


Nobody seems to have pointed out that this declaration is wrong.
There is no type MyUnion_t known. Only "union MyUnion_t" is a
valid type. This is why some people would rather declare the type
in a typedef:

typedef unsion MyUnion_t {
double Double;
char Char;
} MyUnion_t;

Same for structures.


Actually it was pointed out, but of course Usenet is asynchronous.

Code that uses a struct, union, or enum tag as a type name is often an
indication that the author is compiling the code as C++ (which does
allow this).

This is yet another argument against compiling C with a C++ compiler;
you can miss errors like this that will prevent the code from
compiling with a C compiler. If you actually have a need to produce
code that compiles as both C and C++, you need to compile it with both
C and C++ compilers; each will catch errors that the other doesn't.
(If you think you have such a need, it's very likely that you don't.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #6
Keith Thompson wrote:
.... snip ...
Code that uses a struct, union, or enum tag as a type name is often
an indication that the author is compiling the code as C++ (which
does allow this).

This is yet another argument against compiling C with a C++ compiler;
you can miss errors like this that will prevent the code from
compiling with a C compiler. If you actually have a need to produce
code that compiles as both C and C++, you need to compile it with both
C and C++ compilers; each will catch errors that the other doesn't.
(If you think you have such a need, it's very likely that you don't.)


You can avoid this by calling gcc through an alias that imposes the
"-x c" option. I call that alias cc, and it automatically appends
--help when no options are given, or imposes "-x c -W -Wall -ansi
-pedantic -Wwrite-strings -Wfloat-equal -gstabs+ -01" for anything
else.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #7
Keith Thompson wrote:

Nobody seems to have pointed out that this declaration is wrong.
There is no type MyUnion_t known. Only "union MyUnion_t" is a
valid type. This is why some people would rather declare the type
in a typedef:

typedef unsion MyUnion_t {
double Double;
char Char;
} MyUnion_t;

Same for structures.


Actually it was pointed out, but of course Usenet is asynchronous.

Code that uses a struct, union, or enum tag as a type name is often an
indication that the author is compiling the code as C++ (which does
allow this).

This is yet another argument against compiling C with a C++ compiler;
you can miss errors like this that will prevent the code from
compiling with a C compiler. If you actually have a need to produce
code that compiles as both C and C++, you need to compile it with both
C and C++ compilers; each will catch errors that the other doesn't.
(If you think you have such a need, it's very likely that you don't.)


You guys are absolutely right about this, thanks for pointing that out!
I kind of missed that (but OTOH it wasn't really the point of my post).
Koen
Nov 14 '05 #8
Koen wrote:
Hi!

Does anyone know what the standard says about the way unions are
stored in C? I mean the following:

Let's say you have a union with a double and a char field:

union MyUnion_t
{
double Double;
char Char;
};

MyUnion_t aUnion;

Is it standardized somehow which byte of the allocated storage the
Char field will use?


Thanks for all the help! I think I can conclude that there is no real
guarantee for the cross-ABI / cross-platform compatibility of binary
dumps.
Koen
Nov 14 '05 #9
Koen <no@ssppaamm.com> wrote:
Thanks for all the help! I think I can conclude that there is no real
guarantee for the cross-ABI / cross-platform compatibility of binary
dumps.


Yes, definitely. It probably will work if you stay with the same
platform, but once the files have to read back in on a different
platform you're out of luck. I learned that the hard way some
years ago...
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #10
Je***********@physik.fu-berlin.de writes:
Koen <no@ssppaamm.com> wrote:
Thanks for all the help! I think I can conclude that there is no real
guarantee for the cross-ABI / cross-platform compatibility of binary
dumps.


Yes, definitely. It probably will work if you stay with the same
platform, but once the files have to read back in on a different
platform you're out of luck. I learned that the hard way some
years ago...


And if your data contains pointers, they won't be usable across
executions of the same program. It might rarely make sense to write
pointers to a file if you're going to read them back in the same
execution of the program.

(I suspect the OP knows this, but we've seen code here that does
this.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Vijai | last post by:
Hello, I apologize if the following are brain-damaged. 1. Is the ABI the document that specifies how objects, methods, functions etc are laid out in libraries? 2. If so, if there exists a...
6
by: Neil Zanella | last post by:
Hello, I would like to know whether the following C fragment is legal in standard C and behaves as intended under conforming implementations... union foo { char c; double d; };
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
16
by: aarklon | last post by:
Hi folks, recently i read the book named assembly language step by step by Jeff Duntemann. in the chapter coding for linux, he has got a paragraph named C calling conventions, which he...
13
by: Kantha | last post by:
Hi all, I have declared an Union as follows typedef union { struct interrupt_bits { unsigned char c_int_hs_fs_status : 1, c_setup_intflag : 1,
67
by: bluejack | last post by:
A recent post asking for help with unions reminded me of this component of the C language that I have only used a couple of times, and those almost entirely out of personal whim -- Unions for the...
10
by: Chimanrao | last post by:
hi, This is what I am trying to do: I am writing program for a OS called Symbian, which uses the gcc compiler. I have the following piece of code class MyAllocator {
19
by: parag_paul | last post by:
what are ABI'sin C++ -Parag
6
by: Ravikiran | last post by:
Hi, I want know the differences between Unions and Structures in C programming. Thank you..
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.