[comp.lang.c] Problems with IBM RS6000 C compiler

friedl@mtndew.UUCP (Stephen J. Friedl) (08/03/90)

Hi folks,

     I'm not sure where this really belongs so I tried the
above groups.  There's no RS6000 group, right?

     I am porting some software to the IBM RS6000, and the C
compiler and I are just not getting along.  I am not sure what is
a compiler bug, what is my bug, and what is a misunderstanding
between me and the various standards that this thing is trying to
match.  I'm using the "xlc" invocation of the compiler plus
referring to the 7 Dec 88 draft of the Standard.  For cross-
checking my work, I am using C Issue 5 (ANSI) on the 3B2%.

------

     First, a bug: the following produces a compiler error:

	1 | #ifdef undef
	    .......a....
a - 1506-199: (S) Expecting macro name on #ifdef or #ifndef directive.

I've seen lots of places use this instead of something like
"#if 0", and my reading of section 3.8 of the standard seems
to specifically indicate that this should be OK.

------

Second, I am having problems with prototypes in header files.  It
seems that this compiler is trying to be compliant with ANSI,
POSIX, and X/Open (plus maybe the SVID) and I just don't know
enough about all these standards to know who to blame for this.

For instance, <sys/stat.h> defines the prototype for stat:

	extern int stat(char *filename, struct stat *stptr);

Shouldn't the "filename" argument be const qualified?  I
use const all over my code, and the compiler throws up on
every usage.  The following other functions are mis-prototyped:

<fcntl.h>	open()  creat()
<sys/types.h>	stat()  mkdir()  chmod()  mkfifo()
<sys/pwd.h>	getpwnam()
<sys/grp.h>	getgrnam()

plus probably others.  Is this supposed to be like this?  Why?

------

The last is the one I am least sure of.  What should happen
with the following test program:

	extern void	foo( void *** );

	typedef struct { int a; long b; } any_type;

	any_type	**array;

	main()
	{
		foo(&array);
	}

It complains with:

	9 |         arrsize(&array);
	   .................a.......
a - 1506-193: (S) Function call arg cannot be assigned to corresponding param.

I just don't get it; the ANSI compiler on the 3B2 doen't complain about this.

------

     Anybody have ideas on any of this?  I am stumped and frustrated.


     Oh, a side note.  This is not a flame on the RS6000.  It is
a phenomenally fast machine -- hey, I compare it to the 3B2 --
and it seems to me that IBM has spent a lot of time on it.  They
are early in the cycle so I don't mind finding a few bugs in the
short term.

     Steve

% - I realize that the 3B2 compiler does not define the ANSI standard,
    and I certainly don't believe that a single test is exhaustive, but
    it does provide a brief sanity check.  OK?

-- 
Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy
+1 714 544 6561  / friedl@mtndew.Tustin.CA.US  / {uunet,attmail}!mtndew!friedl

If the ADA bill is so important, why does Congress exempt itself?

karl@haddock.ima.isc.com (Karl Heuer) (08/04/90)

In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>	1 | #ifdef undef
>	    .......a....
>a - 1506-199: (S) Expecting macro name on #ifdef or #ifndef directive.

Looks like a bug; possibly the compiler (mistakenly) believes that `undef' is
a reserved word.  It isn't (except immediately following `#'), and besides,
the preprocessor isn't supposed to forbid redefinition of keywords.

>[prototypes in header files don't use `const']

This is a bug.  (Easy enough to make, since many of the relevant Standards
give specifications in pre-ANSI C, alas.)

>	extern void	foo( void *** );
>	any_type	**array;
>	foo(&array);
>I just don't get it; the ANSI compiler on the 3B2 doen't complain about this.

User bug, and a bug in the 3b2 compiler.  The code not only violates the
Standard, but it's *wrong*.  It will fail to do the right thing on certain
architectures, and no amount of casting will make it right.

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

jsalter@slo.paloalto.ibm.com (08/04/90)

In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>     I'm not sure where this really belongs so I tried the
>above groups.  There's no RS6000 group, right?

D'is is the place!

>------
>     First, a bug: the following produces a compiler error:
>	1 | #ifdef undef
>	    .......a....
>a - 1506-199: (S) Expecting macro name on #ifdef or #ifndef directive.
>
>I've seen lots of places use this instead of something like
>"#if 0", and my reading of section 3.8 of the standard seems
>to specifically indicate that this should be OK.

I checked my ANSI standard and the only thing I can think of is that
the preprocessor is then available to use #undef as a string literal.

But that's just a guess.  Metaware in ANSI mode complains, while the
standard AIX PS/2 C compiler doesn't think anythings wrong with it.

>------
>Second, I am having problems with prototypes in header files.  It
>seems that this compiler is trying to be compliant with ANSI,
>POSIX, and X/Open (plus maybe the SVID) and I just don't know
>enough about all these standards to know who to blame for this.

If you invoke the compiler as 'xlc', then, as noted in /etc/xlc.cfg,
the preprocessing token _ANSI_C_SOURCE will be defined.  This token
tells the header files that anything outside of the ANSI C (X3.159-1989)
should not be assumed to be available.

>For instance, <sys/stat.h> defines the prototype for stat:
>	extern int stat(char *filename, struct stat *stptr);

<sys/stat.h> is not part of the ANSI C document.  Thus, 'xlc' does not
necessarily have to know about it.

>Shouldn't the "filename" argument be const qualified?  I
>use const all over my code, and the compiler throws up on
>every usage.  The following other functions are mis-prototyped:
>
><fcntl.h>	open()  creat()
><sys/types.h>	stat()  mkdir()  chmod()  mkfifo()
><sys/pwd.h>	getpwnam()
><sys/grp.h>	getgrnam()
>
>plus probably others.  Is this supposed to be like this?  Why?

I believe they are all mentioned in the POSIX 1003.1 document as being
that way.  If you need POSIX stuff, you need to use 'xlc' with the
_POSIX_SOURCE token defined, or use cc.

>Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy
>+1 714 544 6561  / friedl@mtndew.Tustin.CA.US  / {uunet,attmail}!mtndew!friedl


jim/jsalter  IBM AWD, Palo Alto  T465/(415)855-4427   VNET: JSALTER at AUSVMQ
Internet: ibmsupt!jsalter@uunet.uu.net         UUCP: ..!uunet!ibmsupt!jsalter 
	  "I'm going to win.  I always do."
			George Steinbrenner, on ESPN.

henry@zoo.toronto.edu (Henry Spencer) (08/05/90)

In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>For instance, <sys/stat.h> defines the prototype for stat:
>
>	extern int stat(char *filename, struct stat *stptr);
>
>Shouldn't the "filename" argument be const qualified?  I
>use const all over my code, and the compiler throws up ...

The filename *probably* ought to be const qualified, but the current
standards are mostly written in old C and don't specify this.  This
is a difficult problem, although `#define const /* */' can be helpful.

>	extern void	foo( void *** );
>	any_type	**array;
>		foo(&array);
>
>	9 |         arrsize(&array);
>	   .................a.......
>a - 1506-193: (S) Function call arg cannot be assigned to corresponding param.
>I just don't get it; the ANSI compiler on the 3B2 doen't complain about this.

It should.  There is a special-case exemption for implicit conversions to
and from `void *'.  Not `void ***'.  Just `void *'.  Nothing else.  All
other pointer types require explicit conversion.
-- 
The 486 is to a modern CPU as a Jules  | Henry Spencer at U of Toronto Zoology
Verne reprint is to a modern SF novel. |  henry@zoo.toronto.edu   utzoo!henry

diamond@tkou02.enet.dec.com (diamond@tkovoa) (08/06/90)

In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>Hi folks,
Hi Steve.  Say hello to Jeff for me.

>	extern int stat(char *filename, struct stat *stptr);
>Shouldn't the "filename" argument be const qualified?

Suppose someone has a call of the form
  x = stat("myfile", &my_stat);
or
  x = stat(my_mallocked_buffer_p, &my_stat);

stat is not defined by ANSI, so either way, it would not violate ANSI.
But if const is included, it would break a lot of code that presently
works under Unix(tm) operating system.  (I'm not sure what Posix(tm?)
standards say.)  'Fraid I have to disagree with Karl Heuer's answer!

-- 
Norman Diamond, Nihon DEC     diamond@tkou02.enet.dec.com
This is me speaking.  If you want to hear the company speak, you need DECtalk.

scjones@thor.UUCP (Larry Jones) (08/06/90)

In article <1893@tkou02.enet.dec.com>, diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
< In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
< >	extern int stat(char *filename, struct stat *stptr);
< >Shouldn't the "filename" argument be const qualified?
< 
< Suppose someone has a call of the form
<   x = stat("myfile", &my_stat);
< or
<   x = stat(my_mallocked_buffer_p, &my_stat);
< 
< stat is not defined by ANSI, so either way, it would not violate ANSI.
< But if const is included, it would break a lot of code that presently
< works under Unix(tm) operating system.  (I'm not sure what Posix(tm?)
< standards say.)  'Fraid I have to disagree with Karl Heuer's answer!

How would it break code?  It is perfectly valid to assign a pointer
to non-const to a pointer to const as shown in your examples.  It's
only the other direction (assigning a pointer to const to a pointer
to non-const) that requires a cast.

I agree with Steve -- filename should be const just like it is in
all of the stdio functions (according to ANSI).
----
Larry Jones                         UUCP: uunet!sdrc!thor!scjones
SDRC                                      scjones@thor.UUCP
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
The living dead don't NEED to solve word problems. -- Calvin

steve@taumet.com (Stephen Clamage) (08/06/90)

diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:

>In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>>	extern int stat(char *filename, struct stat *stptr);
>>Shouldn't the "filename" argument be const qualified?

>But if const is included, it would break a lot of code that presently
>works under Unix(tm) operating system.  (I'm not sure what Posix(tm?)
>standards say.)

No, it wouldn't break any code.  A const-qualified parameter type may
be passed a non-const argument, but the reverse is not true.  If
the parameter is not const-qualified, you cannot pass it a literal
string without a cast.  So the *failure* to const-qualify will break
existing code.  That is, with the above prototype,
	r = stat("myfile", &data);
is illegal under ANSI.
But given
	extern int stat(const char *, struct stat *);
			^^^^^
the following are legal:
	char *fname; /* not const */
	stat(fname, &data);
	stat("myfile", &data);
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

karl@haddock.ima.isc.com (Karl Heuer) (08/07/90)

In article <1893@tkou02.enet.dec.com> diamond@tkou02.enet.dec.com (diamond@tkovoa) writes:
>In article <476@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>>	extern int stat(char *filename, struct stat *stptr);
>>Shouldn't the "filename" argument be const qualified?
>
>Suppose someone has a call of [one of] the form[s]
>  x = stat("myfile", &my_stat);
>  x = stat(my_mallocked_buffer_p, &my_stat);
>But if const is included, it would break a lot of code that presently works
>under Unix(tm) operating system.  'Fraid I have to disagree with Karl Heuer's
>answer!

Sorry, 3.2.2.3 agrees with me.  It doesn't break existing code, because it's
perfectly legal to assign from `char *' to `char const *'.  (Only *removing*
the qualifier requires an explicit cast, and even then you'd better know what
you're doing.)

>stat is not defined by ANSI, so either way, it would not violate ANSI.  (I'm
>not sure what Posix(tm?) standards say.)

True; though the same question could be phrased entirely within the ANSI world
by using, say, strlen() as the example.  The 1988 edition of POSIX doesn't use
prototypes to describe its function interfaces; I hear this has been fixed in
the 1990 edition.  Anyway, if vendors are going to provide a prototype for a
function, they should const-qualify any pointer arguments that it uses for
read-only access.

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