[comp.lang.c] Broken compilers

jamesa%betelgeuse@Sun.COM (James D. Allen) (10/21/88)

In article <35317@XAIT.Xerox.COM>, g-rh@XAIT.Xerox.COM (Richard Harter) writes:
> >As for my opinion:  If your compiler's broken, take it up with your vendor.
>
> ...The things that make programs non
> portable are almost always frills and slop.  Things like passing structures
> are frills.

Among the compiler bugs I have contended with are:

1)
	struct {
		whatever;
	} st;
	. . .
	/* the next will be treated as though it were "foo(&st);"  */
		foo(st);

(To print
	"warning: compiler writer too lazy to implement structure arguments"
 seems far more reasonable than to silently substitute a totally different
 construct just because it *might* have been the programmer's intent.)

2)
	main() {
		short s = -3;
		foo(s);
	}

	foo(s) short s; {
		short *sp = &s;
	/* The next will print -1 rather than -3. */
		printf("%d", *sp);
	}

(I think this arose because a little-Endian compiler was ported to a
 big-Endian machine without ample thought and/or testing.)


These were (supposedly) important commercial compilers, not "toys."
By coincidence they were from the same large vendor.  I won't mention
names but the software house is operated by a magazine columnist
who frequently points out the "design errors" Dennis Ritchie made when
he invented C.  :-}

Moral: Test your compiler.  If it works assume you can use most reasonable
constructs.  If not, warn your fellow netlanders and throw the compiler away.

James D. Allen	-- Still dreaming on my way to H***.

knudsen@ihlpl.ATT.COM (Knudsen) (10/25/88)

In article <73946@sun.uucp>, jamesa%betelgeuse@Sun.COM (James D. Allen) writes:

> 	struct {
> 		whatever;
> 	} st;
> 	/* the next will be treated as though it were "foo(&st);"  */
> 		foo(st);
This is my main objection to structure and array assignment and
passing.  Aside from being hideously wasteful of time and stack space,
they permit common typo errors (omission of &) to go undetected.

> [more code example] 
> (I think this arose because a little-Endian compiler was ported to a
>  big-Endian machine without ample thought and/or testing.)

Big-Endian (walkie-talkie company) micros also pose an interesting
problem in casting an (int *) to a (char *); to do this right
the compiler should add 1, but does not.  No problem once you
realize it -- after all, C is structured assembler, eh?

Actually I like the semantics that casting any pointer to (char *)
means "keep the numerical address value the same."
-- 
Mike Knudsen  Bell Labs(AT&T)   att!ihlpl!knudsen
"Lawyers are like handguns and nuclear bombs.  Nobody likes them,
but the other guy's got one, so I better get one too."

wald-david@CS.YALE.EDU (david wald) (10/25/88)

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
...
>This is my main objection to structure and array assignment and
>passing.  Aside from being hideously wasteful of time and stack space,
>they permit common typo errors (omission of &) to go undetected.

If you consider this a language problem, then why are you writing in the
language that uses both = and == as operators?

This is not a flame against clarity, but, given the general style of C,
the "omission of &" problem doesn't seem a very strong argument.


============================================================================
David Wald                                              wald-david@yale.UUCP
						       waldave@yalevm.bitnet
============================================================================

tim@crackle.amd.com (Tim Olson) (10/25/88)

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
| Big-Endian (walkie-talkie company) micros also pose an interesting
| problem in casting an (int *) to a (char *); to do this right
| the compiler should add 1, but does not.  No problem once you
| realize it -- after all, C is structured assembler, eh?
| 
| Actually I like the semantics that casting any pointer to (char *)
| means "keep the numerical address value the same."

Huh?  Why should a Big-Endian machine add 1 when casting from an (int *)
to a (char *)?  The address that points to an integer also (by
definition) points to the first character at that address (32-bit ints
assumed, here):

		Little Endian			   Big Endian
        byte #   3  2  1  0            	  byte #   0  1  2  3
                +--+--+--+--+                     +--+--+--+--+ 
                |'d|'c|'b|'a|   <- 'abcd'         |'a|'b|'c|'d|   <- 'abcd'
                +--+--+--+--+                     +--+--+--+--+ 
                +--+--+--+--+                     +--+--+--+--+ 
                |00|00|00|03|   <- 3              |00|00|00|03|   <- 3        
                +--+--+--+--+                     +--+--+--+--+
                            ^                     ^
                pointer points here               pointer points here


Both Big Endian and Little Endian are internally consistent.

	-- Tim Olson
	Advanced Micro Devices
	(tim@crackle.amd.com)

ok@quintus.uucp (Richard A. O'Keefe) (10/25/88)

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
>In article <73946@sun.uucp>, jamesa%betelgeuse@Sun.COM (James D. Allen) writes:
>
>> 	struct {
>> 		whatever;
>> 	} st;
>> 	/* the next will be treated as though it were "foo(&st);"  */
>> 		foo(st);

I've been using C since version 6+, and I've never seen a compiler that
did that.  structs and unions have been passed by value since UNIX V7.

>This is my main objection to structure and array assignment and
>passing.  Aside from being hideously wasteful of time and stack space,
>they permit common typo errors (omission of &) to go undetected.

(a) hideously wasteful of time and stack space compared to WHAT?
    No-one is forcing you to pass structs by value if you don't want to.
    And if x and y are struct variables,
	x = y;
    should be at least as fast as anything you could have written to do
    the same job.  C hasn't got array assignment, otherwise the same
    remark would apply.  (struct assignment typically takes NO stack space.)

(b) cc is half a compiler.  The other half is called lint.  There has never
    been any reason why a C compiler couldn't give you a warning message
    when a call disagreed with a function definition in the same file; I've
    met a UNIX C compiler that did it (viva Orion!).

henry@utzoo.uucp (Henry Spencer) (10/25/88)

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
>> 	struct {
>> 		whatever;
>> 	} st;
>> 	/* the next will be treated as though it were "foo(&st);"  */
>> 		foo(st);
>This is my main objection to structure and array assignment and
>passing.  Aside from being hideously wasteful of time and stack space,
>they permit common typo errors (omission of &) to go undetected.

Complain to your compiler vendor(s).  The compilers that *I* work with
won't let you get away with this, and ANSI C won't either.

>Big-Endian (walkie-talkie company) micros also pose an interesting
>problem in casting an (int *) to a (char *); to do this right
>the compiler should add 1, but does not...

Nonsense.  What does it *mean* to do that cast?  You're assuming that
it should get you the low-order char.  If you think of C as "structured
assembler", this might be plausible; if you think of it as a high-level
language -- which it is -- then there is no justification for this.
-- 
The dream *IS* alive...         |    Henry Spencer at U of Toronto Zoology
but not at NASA.                |uunet!attcan!utzoo!henry henry@zoo.toronto.edu

peter@ficc.uu.net (Peter da Silva) (10/26/88)

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
...
>This is my main objection to structure and array assignment and
>passing.  Aside from being hideously wasteful of time and stack space,
>they permit common typo errors (omission of &) to go undetected.

I brought this up, and it was pointed out that this is what function
prototypes are for. I'm happy with this, and as soon as they bring the
compiler I use up to X3J11 I'll be ecstatic.

Don't worry. Be happy. it's in there.
-- 
Peter da Silva  `-_-'  Ferranti International Controls Corporation
"Have you hugged  U  your wolf today?"     uunet.uu.net!ficc!peter
Disclaimer: My typos are my own damn business.   peter@ficc.uu.net

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

In article <7356@ihlpl.ATT.COM> knudsen@ihlpl.ATT.COM (Knudsen) writes:
>Actually I like the semantics that casting any pointer to (char *)
>means "keep the numerical address value the same."

Conversion from a (object *) to a (char *) produces a pointer to
the first byte in the object (thought of as an array of bytes).
Whether the first byte is most or least significant within a
larger machine integer depends on the architecture.
The numerical address (i.e. what you'd get by casting to an
integer) need not be the same for the two pointer sizes,
although it often will be.

chip@ateng.ateng.com (Chip Salzenberg) (11/13/88)

According to g-rh@XAIT.Xerox.COM (Richard Harter):
>	More to the point, if your coding practices use constructs and
>techniques that break compilers, you are laying problems up for yourself
>and others in the future.  

It's true that all compilers are broken to some extent.  The real question
is what to do about it.  I personally write C -- using the *entire* language
-- and install workarounds later as needed.

There is no way to predict compiler bugs, especially in view of buggy
compiler updates.  Avoiding things that *might* break is a shell game that
can never be won.  I, myself, don't play the game.

>Writing clean C is no harder than writing dirty C.
>But the price of writing dirty code is high -- debugging dirty code is a
>real pain, and it is a gratuitously assumed cost.  

Code that uses the *entire* language defined in K&R is not "dirty" for it.
Further, the coding style that Mr. Harter calls "clean" I would call
"running scared".  I can imagine Mr. Harter considering a nice C trick:
"I know that K&R says it's okay, but what if some compiler doesn't like it?
I'd better not risk it."

Personally, I write C, not a subset thereof.
-- 
Chip Salzenberg             <chip@ateng.com> or <uunet!ateng!chip>
A T Engineering             Me?  Speak for my company?  Surely you jest!
	   Beware of programmers carrying screwdrivers.