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