extern "C" struct -> class

D

Daniele Benegiamo

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;
}

<<<<<<<<<<<<<<<<
 
M

Maxim Yegorushkin

Daniele said:
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
{
// ...
};
 
D

Daniele Benegiamo

Maxim said:
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
 
M

Maxim Yegorushkin

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.
 
C

cipherpunk

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.
 
M

Marc Mutz

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
 
D

Daniele Benegiamo

... 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.
 
D

Daniele Benegiamo

Daniele said:
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
 
C

cipherpunk

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.
 
C

cipherpunk

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.
 
M

Marc Mutz

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
 
C

cipherpunk

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.
 

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

No members online now.

Forum statistics

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

Latest Threads

Top