[net.lang.c++] C++ problems with DMD code

gaulke@uiucdcsp.CS.UIUC.EDU (09/19/86)

I have found a problem with C++ when using it to write code for the DMD.
The following is part of the output of the preprocessor when including the
file <blit.h> for a simple program.

typedef	int (*ptr_fint)();
main()
{
	(*((int (*)())((ptr_fint *)0x0071d700)[ 43]))( 1 );
}

I don't understand what the above jumble is, but it compiles fine using cc.
CC, however, gives the following error message:

line 4: error: un expected 1 argument for ?
1 error

I am using version 1.0.  Is this a problem with 1.1 as well?

Thanks for any help,

				Dave Gaulke

				gaulke@a.cs.uiuc.edu
				...!{cmcl2,seismo,ihnp4}!uiucdcs!gaulke

karl@haddock (09/22/86)

gaulke@uiucdcsp.CS.UIUC.EDU (Dave Gaulke) writes:
>I have found a problem with C++ when using it to write code for the DMD.
>The following is part of the output of the preprocessor when including the
>file <blit.h> for a simple program.
>
>typedef int (*ptr_fint)();
>main() { (*((int (*)())((ptr_fint *)0x0071d700)[ 43]))( 1 ); }

The problem is that "int (*)()" in oldC means "pointer to function returning
int" whereas in C++ it means "pointer to function taking no arguments and
returning int".  "typedef int (*ptr_fint)(...);" is the correct declaration
in C++, and presumably there's a macro somewhere in blit.h that uses the
oldC cast "(int (*)())" which should be "(int (*)(...))" in C++.

The other compatibility problem which came up recently was a collision
between a structure tag and a variable (which share one namespace in C++).

Bjarne: is there a CC option that gives you compatibility with oldC in these
two cases?  Also, ANSI C preserves the oldC meaning of "int (*)()" and adds
"int (*)(void)" for functions with no arguments.  Will C++ switch to this
notation?  Does it currently accept this notation?

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

guido@mcvax.uucp (Guido van Rossum) (09/23/86)

In article <66700003@uiucdcsp> gaulke@uiucdcsp.CS.UIUC.EDU writes:
>
>typedef	int (*ptr_fint)();
>main()
>{
>	(*((int (*)())((ptr_fint *)0x0071d700)[ 43]))( 1 );
>}
>
>I don't understand what the above jumble is, but it compiles fine using cc.
>CC, however, gives the following error message:
>
>line 4: error: un expected 1 argument for ?

You should have analyzed the jumble a bit more before complaining about
it, as it really does contain an error for CC.  The statement means the
following in C:
	1. take the constant 0x0071d700
	2. cast it to pointer to ptr_fint
	3. considering it as pointing to an array, take element 43 (of
	  type ptrf_fint)
	4. now cast it to pointer to function returning pointer to int
	5. finally call the function pointed to with an argument of 1.

The same error is emitted by CC for a more conventional fragment like this:

	extern int f();
	main() { f(1); }

	"x.c", line 2: error: un expected 1 argument for f()

The error is simply that f() is declared as a function with no argument,
but called as a function with one argument.  This is an error in C++,
but not in C.  Unfortunately C++ has chosen a different solution to cope
with this incompatibility than [proposed] ANSI C; in ANSI C, f() means
that f's arguments are unknown, and one writes f(void) to state
explicitly that f has no arguments.  In your case, the meaning of the
C code changes in C++: line 4 casts to pointer to function with no
arguments and returning pointer to int.

Your error message looks a bit strange because the function name is
unknown.  Another plea for less cryptic error messages in compilers is
in order.
-- 
	Guido van Rossum, CWI, Amsterdam <guido@mcvax.uucp>