[gnu.g++.bug] g++ core dump from improper use of extern "C"

Raeburn@ATHENA.MIT.EDU (Ken Raeburn) (01/05/90)

(version 1.36.1, vax)

Source file:

	extern "C" {
	    extern void foo (struct frob *);
	};

	struct frob {
	    int a, b;
	};

Results:

 % g++ -O -v -g -c bar.c
gcc version 1.36.1 (based on GCC 1.36)
 /mit/gnu/vaxlib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dvax -Dunix -D__vax__ -D__unix__ -D__OPTIMIZE__ bar.c /usr/tmp/cc005284.cpp
GNU CPP version 1.36
 /mit/gnu/vaxlib/gcc-cc1plus /usr/tmp/cc005284.cpp -fcombine-regs -fstrength-reduce -quiet -dumpbase bar.c -g -O -version -o /usr/tmp/cc005284.s
GNU C++ version 1.36.1 (based on GCC 1.36) (vax) compiled by GNU C version 1.36.
default target switches:
bar.c:7: Segmentation violation
g++: Program cc1plus got fatal signal 11.

-- Ken

pcg@aber-cs.UUCP (Piercarlo Grandi) (01/07/90)

In article <9001051018.AA05287@multics.MIT.EDU> Raeburn@ATHENA.MIT.EDU (Ken Raeburn) writes:
    
    (version 1.36.1, vax)
    
    Source file:
    
    	extern "C" {
    	    extern void foo (struct frob *);
    	};
    
    	struct frob {
    	    int a, b;
    	};

and it chokes.... Too bad :->. In any case, you *should not* put a semicolon
at the end of an extern "C" block. This is also the likely reason of the
core dump, because using 'struct some *' before having seen 'struct some {
....' is legal and without problem in both C and C++, or else mutually
"recursive" data structures would not be possible.
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

T.Day@ucl-cs.UUCP (01/09/90)

From: Tim Day <T.Day@uk.ac.ucl.cs>

Piercarlo "Peter" Grandi writes:
> using 'struct some *' before having seen 'struct some {...'
> is legal and without problem in both C and C++

Not quite.  You have to say
	struct frob;
before you can use pointers or references to frob.
Inserting this line at the start of your example code causes it compile
OK (on a Sun3).  The core dump instead of error message is still a bug though.

+-----------------------------------------------------------------------------+
Tim Day                           | Meet every second in life as challenge;
Department of Photogrammetry      | Respond fully to whatever happens
UCL, Gower St., London  WC1E 6BT  |  without anxiety, or complaint, or clinging
+-----------------------------------------------------------------------------+

pcg@aber-cs.UUCP (Piercarlo Grandi) (01/12/90)

In article <494@ucl-cs.UUCP> T.Day@ucl-cs.UUCP writes:
    From: Tim Day <T.Day@uk.ac.ucl.cs>
    
    Piercarlo "Peter" Grandi writes:
    > using 'struct some *' before having seen 'struct some {...'
    > is legal and without problem in both C and C++
    
    Not quite.  You have to say
    	struct frob;
    before you can use pointers or references to frob.

Not really, neither in C nor in C++. Try compiling:

	struct a {struct b *b;} a;
	struct b {struct a *a;} b;

It shall work, both in C and C++. There has never been a
requirement that the name of a struct be known before its use,
if its use is to declare a pointer to the struct. The compiler
need not bother; anything that comes after 'struct' must be a
struct name, and a pointer has always the same size.

You are confusing this point with the the fact that in C++,
saying 'struct a;', which in it as well as in C++ is an empty
declaration, and no special construct all, also has the effect
of typedef'ing 'a' as 'struct a'. The compiler needs to know
that a name is a typedef, otherwise parsing declarations cannot
be done.

In this, the C++ practice of saying 'class c;' is NOT a forward
declaration; it i just the old harmless practice of having empty
declarations, coupled with the new side effect of having an
implicit typedef. Saying beforehand 'class c;' in C++ is not
needed if you write 'class c *m;' instead of 'c *m;'.

The effect is the same if you just say 'typedef class a ;'.
With the following preprocessor macro you get the same effect
in C:

	#define mode(FLAVOR,NAME) \
		typedef FLAVOR NAME NAME; FLAVOR NAME

Note that the typedef appears *before* the struct definition, if
any; if you follow this with a ';' the struct definition becomes
a harmless empty delcaration.

You can use this in C as

	mode(struct,complex) { float re,im; };
	complex a,b,c;

or

	mode(struct,clutch);
	mode(struct,car) { ...; clutch *theClutch; ... };

just like in C++, if you have got fed up with using leading
'struct', 'union', 'enum' (enums are special though in C)...
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk