Topic: C and C++ together. (structure feature request)
Author: kanze@us-es.sel.de (James Kanze)
Date: 07 Apr 1994 10:48:07 GMT Raw View
In article <MAYER.94Mar28110010@orthanc.sono.uucp> mayer@sono.uucp
(Ron Mayer) writes:
|> <KANZE.94Mar24145214@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze):
|> >In article <MAYER.94Mar17212844@orthanc.sono.uucp> mayer@sono.uucp
|> >(Ron Mayer) writes:
|> >><IRVINE.94Mar14060448@hopi.lks.csi.com> irvine@lks.csi.com (Chuck Irvine):
|> >>> Works quite well. See extern "C".
|> >> Yes, but is there anything especially tricky I need to watch out for?
|> >> [...]
|> >> For example, can I assume that all struct's will have the format in
|> >> code compiled with both languages?
|> >Formally, where the padding goes in struct's is implementation
|> >defined. So there is no guarantee. [...] So if the C and the C++
|> >compiler are from the same vendor (or the C++ compiler generates C),
|> >you are *probably* safe.
|> Yes, "*probably*"... In some situations it is quite risky to make
|> such an assumption, and for some applications I'd almost recommend
|> avoiding mixing C and C++ libraries unless you know exactly how your
|> compiler creates it's data structures. (Which IMHO is unfortunate, since I
|> would have hoped that such details would be invisible to the programmer.)
In some cases, you don't even have to mix languages. I've seen C and
C++ compilers which have a command line option to control padding; one
setting optimizes for speed, by aligning all int's on even addresses,
and the other for space, by not aligning them.
So not only does the library have to be compiled with the same vendors
compiler, it has to be compiled with the same compiler options.
--
James Kanze email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
Author: mayer@sono.uucp (Ron Mayer)
Date: Mon, 28 Mar 1994 19:00:10 GMT Raw View
<KANZE.94Mar24145214@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze):
>In article <MAYER.94Mar17212844@orthanc.sono.uucp> mayer@sono.uucp
>(Ron Mayer) writes:
>><IRVINE.94Mar14060448@hopi.lks.csi.com> irvine@lks.csi.com (Chuck Irvine):
>>>
>>> Works quite well. See extern "C".
>>
>> Yes, but is there anything especially tricky I need to watch out for?
>> [...]
>> For example, can I assume that all struct's will have the format in
>> code compiled with both languages?
>
>Formally, where the padding goes in struct's is implementation
>defined. So there is no guarantee. [...] So if the C and the C++
>compiler are from the same vendor (or the C++ compiler generates C),
>you are *probably* safe.
Yes, "*probably*"... In some situations it is quite risky to make
such an assumption, and for some applications I'd almost recommend
avoiding mixing C and C++ libraries unless you know exactly how your
compiler creates it's data structures. (Which IMHO is unfortunate, since I
would have hoped that such details would be invisible to the programmer.)
I think I've been bitten by this risk quite recently. For example,
with GCC it looks as if you stop being safe as soon as you start using
their zero-length-datastructure extention, as evidenced by the example
following my .sig
I guess what I'd really like is a request that c++ extend the
extern "C" concept to apply to structure declarations too; and
compiler vendors could then guarantee that
extern "C" struct stat {...}
would use some architecture-dependant-standard rules for organizing
their data types (preferably identical to whatever compiler created
the OS's system calls). I sure would hate it if some c++ compiler
decided to insert extra padding next time someone did syscall(SYS_stat,...).
Is this a reasonable request?
Ron Mayer
mayer@orthanc.acuson.com
Example of different C and C++ data types with gcc and the
zero-sized structure language extention. Yes, I know the
code below is not a good idea anyway, but it was the simplest
case I could think of which demonstrates my concern...
prompt% cat > foobar.h
typedef struct MyStruct {
int num_items;
int bytes_per_item;
union {char c[0];short s[0];long l[0];} data;
} MyStruct;
prompt% cat > foo.cc
#include "foobar.h"
MyStruct x[2];
extern "C" void bar(MyStruct x[]);
main()
{
x[0].num_items=10;
x[1].num_items=11;
bar(x);
}
prompt% cat > bar.c
#include "foobar.h"
void bar(MyStruct x[]) {
printf("%d\n",x[0].num_items);
printf("%d\n",x[1].num_items);
}
prompt% gcc foo.c bar.c
prompt% a.out
10
0