| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"Vincezo Ciaschini" |
| Date: |
09 Jun 2005 09:06:58 AM |
| Object: |
Question about C/C++ struct memory layout compatibility |
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
Thanks in advance,
Vincenzo
.
|
|
| User: "Shezan Baig" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:02:35 AM |
|
|
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
I don't think so. I believe it violates the One Definition Rule. But
I'm not sure if this applies when mixing C and C++.
-shez-
.
|
|
|
| User: "Vincezo Ciaschini" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:20:42 AM |
|
|
Shezan Baig wrote:
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
I don't think so. I believe it violates the One Definition Rule. But
I'm not sure if this applies when mixing C and C++.
My doubt exactly, especially considering that the two definition are
identical with respect to the included data.
It seems reasonable to me that, if the data definition part is
identical, and there is no virtual/RTTI on the C++ part, that the memory
layout should be identical. However, I am not certain about this.
Also, the cppsrc.cc code will be in a library linked by the csrc.c (and
a main() function) code.
Bye,
Vincenzo
-shez-
.
|
|
|
| User: "=?ISO-8859-15?Q?Juli=E1n?= Albo" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:30:12 AM |
|
|
Vincezo Ciaschini wrote:
It seems reasonable to me that, if the data definition part is
identical, and there is no virtual/RTTI on the C++ part, that the memory
layout should be identical. However, I am not certain about this.
I think is unreasonable to worry about that. Just write a class that derives
from or contains the C style struct and use it from C++.
--
Salu2
.
|
|
|
|
|
|
| User: "Victor Bazarov" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 09:30:22 AM |
|
|
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
I have no definite answer to this question. I believe, though, that
it would be implementation-specific. However, regardless of what I
believe, I'd like to know *why* would you want to do something like
that. Why do you feel the need to have both C and C++ translation units
in the same program?
V
.
|
|
|
| User: "Andre Kostur" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 12:06:38 PM |
|
|
Victor Bazarov <v.Abazarov@comAcast.net> wrote in news:8oYpe.81965
$NC6.43494@newsread1.mlpsca01.us.to.verio.net:
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
I have no definite answer to this question. I believe, though, that
it would be implementation-specific. However, regardless of what I
believe, I'd like to know *why* would you want to do something like
that. Why do you feel the need to have both C and C++ translation
units
in the same program?
Arguably wouldn't that violate the One Definition Rule ?
.
|
|
|
|
| User: "Vincezo Ciaschini" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:12:51 AM |
|
|
Victor Bazarov wrote:
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
struct s {
int c;
char v;
#if defined(__cplusplus)
s();
s(double);
method1(int);
method2(float);
#endif
};
and then two sources,
-- cppsrc.cc --
#include "head.h"
extern "C" {
s *create(void)
{
s *res = new s(1.0);
res->method1(4);
return res;
}
-- csrc.c --
#include "head.h"
extern struct s *create(void);
int f()
{
struct s* val = create();
val->v = 'd';
}
Is this legal/portable?
I have no definite answer to this question. I believe, though, that
it would be implementation-specific. However, regardless of what I
believe, I'd like to know *why* would you want to do something like
that. Why do you feel the need to have both C and C++ translation units
in the same program?
Because they would not be in the same program. The cppsrc.cc would be
in a dynamic library that will be linked to the program containing
csrc.c. It is an effort to provide a C interface to a C++ library.
Bye,
Vincenzo
V
.
|
|
|
| User: "Shezan Baig" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:22:42 AM |
|
|
Vincezo Ciaschini wrote:
Because they would not be in the same program. The cppsrc.cc would be
in a dynamic library that will be linked to the program containing
csrc.c. It is an effort to provide a C interface to a C++ library.
You probably need to make a clean-cut between the C++ interface and the
C interface, instead of attempting to mix them both in a single header
file. Use 2 header files:
head.h
------
normal C++ declaration here
head_c.h
--------
C declarations here
hth,
-shez-
.
|
|
|
|
| User: "Victor Bazarov" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:25:54 AM |
|
|
Vincezo Ciaschini wrote:
Victor Bazarov wrote:
[...] I'd like to know *why* would you want to do something like
that. Why do you feel the need to have both C and C++ translation units
in the same program?
Because they would not be in the same program. The cppsrc.cc would be
in a dynamic library that will be linked to the program containing
csrc.c.
Read your own statement again. If it is _linked_, it's in the same
program. By definition.
It is an effort to provide a C interface to a C++ library.
I don't see any need to have a C struct created in C++ code and returned
by a C function. It would be best to de-couple them altogether and use
some kind of "handle" to identify your C++ object inside your C++ space.
Your library is the only thing that should know about the inner workings
of that object. The outside world should use the C interface to do all
the processing. Passing the "handle" back and forth is the only answer
AFAIK.
<offtopic> But is it really needed to have C interface? How many
customers do you have that use C versus C++ bindings? Any at all?
Never mind. Marketing decisions are not necessarily based on common
sense. And don't tell me that having a C interface is not a marketing
decision.
</offtopic>
V
.
|
|
|
| User: "Pete Becker" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:33:01 AM |
|
|
Victor Bazarov wrote:
And don't tell me that having a C interface is not a marketing
decision.
It's often a sensible engineering decision. C interfaces are far less
dependent on the compiler you're using than C++ interfaces, so a shared
library with a C interface is more broadly useful than a shared library
with a C++ interface. Having a well-defined C++ ABI for the platform
you're targeting makes this less of a problem, to the extent that the
ABI really is well-defined.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
.
|
|
|
|
| User: "Shezan Baig" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:32:40 AM |
|
|
Victor Bazarov wrote:
<offtopic> But is it really needed to have C interface? How many
customers do you have that use C versus C++ bindings? Any at all?
Never mind. Marketing decisions are not necessarily based on common
sense. And don't tell me that having a C interface is not a marketing
decision.
</offtopic>
Sometimes it is just a case that certain developers at the company who
are "afraid" to use C++. Sounds silly, yes. But we all cannot control
everybody :(
-shez-
.
|
|
|
|
|
|
|
| User: "Rapscallion" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
09 Jun 2005 10:37:17 AM |
|
|
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
....
Is this legal/portable?
Maybe. But the classic way to provide a C interface for a C++ program
goes like this:
// somefile.h ----------------------
struct s; // declaration
extern "C" {
struct s *create(void);
void destroy (struct s* x);
void method1 (struct s* x, int);
// ...
}
// somefile.cpp --------------------
struct s {
s();
s(double);
method1(int);
method2(float);
private:
int c;
char v;
};
s *create(void)
{
struct s *res = new s(1.0);
res->method1(4);
return res;
}
void destroy (struct s* x) { ... }
void method1 (struct s* x, int) { ... }
// the C user ------------------------
int main() {
struct s* val = create();
method1 (s, 33);
destroy (s);
}
.
|
|
|
| User: "Rene Moehring" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
10 Jun 2005 02:00:35 AM |
|
|
On 9 Jun 2005 08:37:17 -0700, Rapscallion wrote:
Vincezo Ciaschini wrote:
Supposing you have the following declaration in a header file:
-- head.h --
...
Is this legal/portable?
Maybe. But the classic way to provide a C interface for a C++ program
goes like this:
// somefile.h ----------------------
struct s; // declaration
extern "C" {
struct s *create(void);
void destroy (struct s* x);
void method1 (struct s* x, int);
// ...
}
// somefile.cpp --------------------
struct s {
s();
s(double);
method1(int);
method2(float);
private:
int c;
char v;
};
s *create(void)
{
struct s *res = new s(1.0);
This new could throw an exception. You should use the one that returns a
NULL pointer on error and handle that case.
res->method1(4);
return res;
}
void destroy (struct s* x) { ... }
void method1 (struct s* x, int) { ... }
// the C user ------------------------
int main() {
struct s* val = create();
method1 (s, 33);
destroy (s);
}
--
I'm not a racist. I hate everyone equally!
.
|
|
|
| User: "Rapscallion" |
|
| Title: Re: Question about C/C++ struct memory layout compatibility |
10 Jun 2005 03:52:26 AM |
|
|
Rene Moehring wrote:
On 9 Jun 2005 08:37:17 -0700, Rapscallion wrote:
....
s *create(void)
{
struct s *res = new s(1.0);
This new could throw an exception. You should use the one that returns a
NULL pointer on error and handle that case.
res->method1(4);
return res;
}
Good point. Not only new may throw but also 'res->method1(4)'. One
needs to surround function bodies with try {} catch (...){} blocks.
.
|
|
|
|
|
|

|
Related Articles |
|
|