Re: getopt() prototype [was: checkin-message of something or other]

On Thu, Oct 12, 2000 at 10:11:41AM -0700, Fred L. Drake wrote: [ use -Wall and -Wstrict-prototypes by default, if the compiler is gcc ]
There is one known warning at this time, caught by the -Wstrict-prototypes option. In Modules/main.c, the declaration of getopt() without parameters gets a complaint (rightly) that it is not a proper prototype. The lack of a complete prototype information should be corrected when the right portability conditions have been identified.
I already looked at this before, and the problem is that the prototype for getopt is not portable (because of quirks in the ANSI C standard regarding 'compatible' pointer types.) Some systems define it as 'const char **' (or 'char const **'), some perhaps as 'char **', and some as 'char * const *'. 'const char **' and 'char const **' are the same, but 'char * const *' is something else, and so is 'char **'. 'char * const *' and 'char **' are equivalent types, meaning that conforming compilers should be able to intermix them without problems, but 'const char **' is a different type, and ANSI C either demands or strongly suggests a warning. (Why exactly it's a different type is mostly a choice of language, though I'm sure there are people who would defend the choice. What it means it that you can't mix two layers of indirection with qualifiers like 'const' or 'volatile', without paying close attention to assignment and prototypes :P) As a result, no matter what prototype we think up, we're always screwing either the one type of platform or the other. And not with a warning; the conflicting prototype would generate an error, nto a warning. The only solution I can think of is adding the proper prototype to the pyport.h header file, inside a proper #ifdef. For generated code it doesn't really matter which of the prototypes is used, but if the system headers do provide a prototype, and it doesn't match in indirect-constness, compilation will fail. (In other words, even on the platforms that are missing it, close attention should be paid to the manual pages, trying to guess what the prototype is going to look like if that particular system would ever grow a prototype in a system header. From what I read in the getopt(3) manpage on my linux box the prototype mixup comes from a POSIX.2 flaw, but I'm not sure.) Does anyone have a system where the prototype to getopt() is not defined in header files ? My Solaris 2.x testbox has that problem, but the box in question is one huge mess, and I doubt it has anything to do with Solaris in particular. I only use it to reproduce reported bugs, not report any myself ;P -- Thomas Wouters <thomas@xs4all.net> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!

[Thomas Wouters, on getopt]
... From what I read in the getopt(3) manpage on my linux box the prototype mixup comes from a POSIX.2 flaw, but I'm not sure.)
I bet it's actually talking about Interpretation 150 to POSIX.2, here (while you can't read the std online, you can read the complaints online!): http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-150. html Doesn't have anything to do with the prototype, alas.
Does anyone have a system where the prototype to getopt() is not defined in header files ? My Solaris 2.x testbox has that problem, but the box in question is one huge mess, and I doubt it has anything to do with Solaris in particular. ...
Sure: Windows doesn't have a getopt; getopt isn't std C (not even in C99). Assorted derived stds demand that a getopt protoptype appear in stdlib.h, and others that it appear in unistd.h. I have a different suggestion: screw it. getopt keeps creating problems on GNUish systems too, because without the POSIXLY_CORRECT envar set, the GNU getopt shuffles all the "option strings" to the front, making a mess of, e.g., python myprog.py -v The Python source tree already has its own getopt implementation (Python/getopt.c) -- let's rename its contained function to PyOS_Getopt, get rid of the irritating __BEOS__ #ifdef'ery therein, prototype it the way we like, and have Python use that instead on all systems. Every second we've spent tracking down problems with platform-supplied getopts has been a waste of time. they've-had-21-years-to-straighten-out-"the-std"-getopt-and-they-blew-it- ly y'rs - tim

On Thu, Oct 12, 2000 at 05:38:13PM -0400, Tim Peters wrote:
[Thomas Wouters, on getopt]
... From what I read in the getopt(3) manpage on my linux box the prototype mixup comes from a POSIX.2 flaw, but I'm not sure.)
I bet it's actually talking about Interpretation 150 to POSIX.2, here (while you can't read the std online, you can read the complaints online!):
http://standards.ieee.org/reading/ieee/interp/1003-2-92_int/pasc-1003.2-150. html
Doesn't have anything to do with the prototype, alas.
Ah, that sounds about right. Nifty link, too. I thought it had something to do with the prototype because of this comment: CONFORMING TO getopt(): POSIX.2, provided the environment variable POSIXLY_CORRECT is set. Otherwise, the elements of argv aren't really const, because we permute them. We pretend they're const in the prototype to be compatible with other systems.
I have a different suggestion: screw it. getopt keeps creating problems on GNUish systems too, because without the POSIXLY_CORRECT envar set, the GNU getopt shuffles all the "option strings" to the front, making a mess of [ a lot of things ]
Ahh, yes, I see Python/getopt.c and the autoconf check that enables it when necessary. Funny, I've seen that file a number of times, and read it, and read the getopt autoconf test as well, but somehow I never connected it with the loose prototype in main.c. I'm +1 on doing what you suggested, then. Wonder why it hasn't been done yet, though... we have no use for a system-wide getopt, except for a slightly smaller binary on systems that do have a 'good' system getopt. We can't use enhancements made to system getopt or anything, anyway.
they've-had-21-years-to-straighten-out-"the-std"-getopt-and-they-blew-it- ly y'rs - tim
what-do-you-want-to-bet-it's-going-to-take-longer-for-Python-getopt-modules- ly y'rs, -- Thomas Wouters <thomas@xs4all.net> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!

I have a different suggestion: screw it. getopt keeps creating problems on GNUish systems too, because without the POSIXLY_CORRECT envar set, the GNU getopt shuffles all the "option strings" to the front, making a mess of, e.g.,
python myprog.py -v
The Python source tree already has its own getopt implementation (Python/getopt.c) -- let's rename its contained function to PyOS_Getopt, get rid of the irritating __BEOS__ #ifdef'ery therein, prototype it the way we like, and have Python use that instead on all systems. Every second we've spent tracking down problems with platform-supplied getopts has been a waste of time.
Excellent. After 2.0. --Guido van Rossum (home page: http://www.python.org/~guido/)
participants (3)
-
Guido van Rossum
-
Thomas Wouters
-
Tim Peters