By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,617 Members | 1,708 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,617 IT Pros & Developers. It's quick & easy.

extern "C" struct -> class

P: n/a
Is the following program standard-compliant? I've compiled it with some
compilers and no errors or warnings are produced, but this is not a
demonstration.

The "incriminated" part is the declaration:

extern "C" struct X;

that is then defined as:

class X {};

I know that 'extern "C"' change only the linkage specification, but
forwarding declarations in C++ /usually/ don't allow usage of different
class-keys.
Regards,
Daniele.

>>>>>>>>>>>>>>>>>


/* declarations */

extern "C" {
struct X;

X * new_X ();
void delete_X (X *);
}

/* definitions */

class X {};
extern "C" {

X * new_X ()
{
return new X ();
}

void delete_X (X * p)
{
delete p;
}

} // extern "C"

int main ()
{
X * p = new_X ();
delete_X (p);
return 0;
}

<<<<<<<<<<<<<<<<
Aug 23 '05 #1
Share this Question
Share on Google+
11 Replies


P: n/a
Daniele Benegiamo wrote:
Is the following program standard-compliant? I've compiled it with some
compilers and no errors or warnings are produced, but this is not a
demonstration.

The "incriminated" part is the declaration:

extern "C" struct X;

that is then defined as:

class X {};

I know that 'extern "C"' change only the linkage specification, but
forwarding declarations in C++ /usually/ don't allow usage of different
class-keys.


To be on the safe side I would derive a class from an extern "C"
struct.

extern "C" struct X { ... };

class X_impl : public X
{
// ...
};

Aug 23 '05 #2

P: n/a
Maxim Yegorushkin wrote:
To be on the safe side I would derive a class from an extern "C"
struct.

extern "C" struct X { ... };

class X_impl : public X
{
// ...
};


But in this way the implementation of functions become more expensive
(as maintenance and probability of bugs), because it needs casting to
works properly. E.g.:

extern "C" struct X { /* empty */ };

class X_impl : public X
{
// ...
};

extern "C"
{

void foo (X * p)
{
X_impl * p2 = static_cast<X_impl *> (p);
// ...
}

void delete_X (X * p)
{
delete static_cast<X_impl *> (p);
}

} // extern "C"

However this is a possible solution. Thanks for your reply.

Daniele
Aug 23 '05 #3

P: n/a

Daniele Benegiamo wrote:

[]
But in this way the implementation of functions become more expensive
(as maintenance and probability of bugs), because it needs casting to
works properly. E.g.:


Well, programming is expensive, it requires typing.

Aug 24 '05 #4

P: n/a
> I know that 'extern "C"' change only the linkage specification,
but forwarding declarations in C++ /usually/ don't allow
usage of different class-keys.


You sure about this?

=====

struct A;

class A {
public:
void foo() {}
};

int main()
{
A a;
return 0;
}

=====

rjh@localhost:~$ g++ test.cc -o t -Wall -W -ansi -pedantic
test.cc: In function `int main()':
test.cc:10: warning: unused variable `A a'

.... According to G++, it's perfectly legal and valid C++ syntax. This
seems like a nonissue to me.

Aug 24 '05 #5

P: n/a
ci********@gmail.com wrote:
<snip>
struct A;

class A {
public:
void*foo()*{}
};

<snip>

Conformant or not, I remember that (some versions of) VC++
errors on this.
(Well, the code in question was class A; struct A {};)

Marc

Aug 24 '05 #6

P: n/a
ci********@gmail.com wrote:
... According to G++, it's perfectly legal and valid C++ syntax. This
seems like a nonissue to me.


As I've written in my first post, the code already compiles with
different compilers, but this is not a demonstration that it is
*standard* C++, so I think it remain an issue.
Aug 24 '05 #7

P: n/a
Daniele Benegiamo wrote:
Is the following program standard-compliant? I've compiled it with some
compilers and no errors or warnings are produced, but this is not a
demonstration.

The "incriminated" part is the declaration:

extern "C" struct X;

that is then defined as:

class X {};

I know that 'extern "C"' change only the linkage specification, but
forwarding declarations in C++ /usually/ don't allow usage of different
class-keys.


I've found a very simple, obvious (after some weeks ;) ), and surely
standard solution to the problem:

struct X {
// Public stuffs...

private:
// Private stuffs...
};

This avoid to mix the class-keys and allow to use the "struct X" as a
normal C++ class in the implementation-side of my library.

Thanks to all repliers!

Daniele
Aug 24 '05 #8

P: n/a
Once you turn on "-ansi -pedantic" in G++, it generally conforms quite
closely to the Standard. I'm not presenting it as a "G++ 4.0 says it's
okay, thus there's no problem"--the world's a lot bigger than any one
compiler--but rather as a "if a generally good compiler with a good
reputation for conformance says, in its strictest conformance mode,
that it's okay, I'm inclined to think that it's conformant to the
Standard".

Besides, the only practical difference between a struct and a class in
C++ is the default access specifier, so I'd be quite surprised if this
turned out to be non-Standard.

Aug 24 '05 #9

P: n/a
Right, but which versions? VC++6 is infamous for being so
poorly-conformant to the Standard that a lot of people, myself
included, think it has little business calling itself a C++ compiler.
GCC 2.91, likewise.

There are lots of non-standards-conformant compilers out there. I
don't think we should take error reports from known-bad compilers as
indicative that something is forbidden by the Standard. Nor should we
let a known-bad compiler's acceptance of something be indicative that
something is allowed.

Aug 24 '05 #10

P: n/a
ci********@gmail.com wrote:
<snip>
Right, but which versions?**VC++6*is*infamous*for*being
so poorly-conformant to the Standard that a lot of
people, myself included, think it has little business
calling itself a C++ compiler. GCC 2.91, likewise.

<snip>

I don't remember exactly where this came up, and I don't
have access to a VC++ compiler atm, but I'm pretty sure
it was one of the 7.x's.

Marc
Aug 25 '05 #11

P: n/a
VC++ 7.1 compiles it without complaint. Kicking the warning level up a
notch gives a warning, but that's all.

Unless someone can present a modern, standards-conformant compiler
which refuses to accept this valid C++, then I think the entire thread
can be put to bed as a nonissue.

Aug 25 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.