[comp.lang.c] Bugs in OS9/68K C-Compiler ?

peters@fbihh.UUCP (Heino Peters) (10/24/88)

Hi there,

recently a friend tried to port some software from unix to OS9. He ran
into unexpected trouble doing that, so he asked for my help. When i tried
to locate the troublespots i found several interesting things about
the Microware C-Compiler V3.0 running under OS9/68K V2.2. Here's the upshot
of all that.

The first problem was with long lines. The C-compiler would complain about
long lines even if they were simply comments. These comments were supposed
to be read by an automatic documentation system, so they went over several
lines finished by "\" to yield one long single line.

Now for the more serious things. The following source:

#define A(x) B(x)
#define B(x) (x)

main()

{
 struct { int a } b;

 printf( "%d\n", A(A(b)).a );
}

yields these complaints from the compiler:

"cc.c", line 9: ****  struct/union object required ****
 printf( "%d\n", (A(b)).a );
                   ^
"cc.c", line 9: ****  lvalue required ****
 printf( "%d\n", (A(b)).a );
                   ^
errors in compilation : 2

Obviously the problems with macros like CAR(CAR(x)) arn't all gone.
Another goodie is the following source:

tgetflag ()
{
  char *ptr = (char *) any_fun ();
  return 0 != ptr ;
}

which will give the follownig message when compiled:

"p.c", line 4: ****  illegal type combination ****
  return 0 != ptr ;
              ^
errors in compilation : 1

please note: "return ptr != 0" will compile.
The following little program will drive the compiler real crazy:

#define Y(t) ('t')
main()
{
 printf( "%d\n", Y(a) );
}

The messages look like this (please note: there are ^a's around the a's
although there is no ^a in the source):

"tt.c", line 5: ****  unterminated character constant ****
 printf( "%d\n", ('a') );
                  ^
"tt.c", line 5: ****  ) expected ****
 printf( "%d\n", ('a') );
                    ^
"tt.c", line 5: ****  ) expected ****
 printf( "%d\n", ('a') );
                    ^
"tt.c", line 5: ****  ; expected ****
 printf( "%d\n", ('a') );
                    ^
"tt.c", line 5: ****  bad character ****
 printf( "%d\n", ('a') );
                     ^
"tt.c", line 5: ****  unterminated character constant ****
 printf( "%d\n", ('a') );
                       ^
"tt.c", line 5: ****  undeclared identifier ****
 printf( "%d\n", ('a') );
                    ^
"tt.c", line 5: ****  warning - expression with little effect ****
 printf( "%d\n", ('a') );
                    ^
"tt.c", line 5: ****  ; expected ****
 printf( "%d\n", ('a') );
                       ^
"tt.c", line 5: ****  warning - expression with little effect ****
 printf( "%d\n", ('a') );
                       ^
"tt.c", line 5: ****  ; expected ****
 printf( "%d\n", ('a') );
                         ^
"tt.c", line 5: ****  syntax error ****
 printf( "%d\n", ('a') );
                         ^
errors in compilation : 10

Well and now for the one, that got me nearly mad till i found the buster:

main()

{
 char x = 'D';

 switch( x )
  {
   int i;

   case 'D':
    printf( "Hi there" );
  }
}

This will compile without complaints (*REALLY*), but the code produced for
th switch statement looks like this:

...
 bra _6
 subq.l #4,sp :2
_7
 lea _8(pc),a0
 move.l a0,d0 :2
 bsr printf
 addq.l #4,sp :2
 bra _5
_6
 move.b 1(sp),d0
 ext.w d0 :2
 cmpi.w #68,d0
 beq _7
_5
...

This code jumps around the allocation of stack space for variable i, but will
deallocate this space, so the next return instruction  will end in nirwana :-(

All of these little buggers compiled and ran just fine on my unix box. Maybe
i'm missing something, but these look just like errors in the Microware
compiler. Has somebody out there any comments or patches ?

So long, Heino.

---------------------+---------------------------------------------------------
Heino Peters         | email:
Universitaet Hamburg | peters@rz.informatik.uni-hamburg.dbp.de (preferred)
Bodenstedtstr. 16    | peters@fbihh.uucp (...!uunet!unido!fbihh!peters)
D-2000 Hamburg 50    | ...!{tmpmbx,altger}!althh!ccsq!hphal!heino (privat)
---------------------+---------------------------------------------------------

rzmul3@tuvie (Uni Leoben) (10/26/88)

Hi Heino,

Seems like most of your troubles are a result from the Microware CPP.
The Decus CPP (ported to OS-9 by the TOP people) handles all of your example 
programs correct. It doesn't support the -g debugging option, though.

For the 'return 0 != ptr' problem : I don't know why, but 'return ptr != 0'
works. Apparently the compiler automatically casts integers to pointers
on comparisons but doesn't cast pointers to integers. I don't know what
K&R says to this case. Perhaps someone with more C insight could comment
on this.

-- Tom Leitner / Joanneum Research Association / Austria

gwyn@smoke.BRL.MIL (Doug Gwyn ) (10/28/88)

In article <636@tuvie> rzmul3@tuvie (Uni Leoben) writes:
>For the 'return 0 != ptr' problem : I don't know why, but 'return ptr != 0'
>works. Apparently the compiler automatically casts integers to pointers
>on comparisons but doesn't cast pointers to integers.

That certainly is a confused compiler.  != is a symmetric operator.

It is not a matter of a cast (do YOU see a cast?) nor even of a type
conversion.  Any pointer may be compared for (in)equality with a null
pointer, and 0 is one way to write a null pointer constant (in ANSI C,
(void*)0 is another).  I think most programmers would find
	return ptr != 0;
clearer than
	return 0 != ptr;
but these are technically equivalent.

guy@auspex.UUCP (Guy Harris) (10/28/88)

>For the 'return 0 != ptr' problem : I don't know why, but 'return ptr != 0'
>works. Apparently the compiler automatically casts integers to pointers
>on comparisons but doesn't cast pointers to integers. I don't know what
>K&R says to this case.

K&R say that both

	0 != ptr

and

	ptr != 0

should cause 0 to be cast to the type of the pointer "ptr".  It should
not cast "ptr" to "int" in *either* case.

blarson@skat.usc.edu (Bob Larson) (10/28/88)

In article <636@tuvie> rzmul3@tuvie (Uni Leoben) writes:
>For the 'return 0 != ptr' problem : I don't know why, but 'return ptr != 0'
>works. Apparently the compiler automatically casts integers to pointers
>on comparisons but doesn't cast pointers to integers. I don't know what
>K&R says to this case. Perhaps someone with more C insight could comment
>on this.

The order of the comparison dosn't matter, 0 must be converted to the
approprate type.

char *ptr;
return 0 != ptr;

is equivelent to:

char *ptr;
return (char *)0 != ptr;

(I'm quite sure K&R, H&S, K&R-II, and the ANSI drafts all argee on this.)
[Microware is gradually converting from a K&R based compiler to an ANSI
one, when I talked to him a few years ago Kim Kempf (microware's C
compiler guru) was on the ANSI committee.]
-- 
Bob Larson	Arpa: Blarson@Ecla.Usc.Edu	blarson@skat.usc.edu
Uucp: {sdcrdcf,cit-vax}!oberon!skat!blarson
Prime mailing list:	info-prime-request%ais1@ecla.usc.edu
			oberon!ais1!info-prime-request