ado@elsie.UUCP (Arthur David Olson) (06/06/88)
Here's another "help wanted on a comment to X3J11" request. One of the comments I sent in during the second public review period ran along these lines: Rationale, Sectioin 3.8.3, Page 64 Description: Contains a sample keyword redefinition: #define void int along with a note that "The redefinitions of void and const could be useful in retrofitting more modern C code to an older implementation." Since the Standard requires a void * to have the same representation as a char *, and since a char * may not have the same representation as an int *, this definition seems suboptimal. Proposed Change: Change the above line to read #define void char The response I received (was marked "Not an official X3J11 document"), said that while "#define void char" might be better when it comes to pointers, there were other cases where "#define void int" was better. Can anyone give a concrete example? -- Market swaps ends for Chinese native. (5) ado@ncifcrf.gov ADO is a trademark of Ampex.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/06/88)
In article <8085@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >The response I received (was marked "Not an official X3J11 document"), >said that while "#define void char" might be better when it comes to pointers, >there were other cases where "#define void int" was better. Can anyone give a >concrete example? There have been compilers that either did not know about "void" at all, or that had various breakages involving e.g. pointers to functions returning void (some of the Berkeley compilers had that problem). Thus, when compiling code such as void func() { extern void exit(); /* ... */ } it has often been useful to do the equivalent of "cc -Dvoid=int file.c". Using char instead of int would not only gain nothing, but it would introduce possible error (since in such an implementation, exit() would probably be defaulted to return int). Until recently, there has not been code containing void *, but there has been lots of code like the above example.
lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (06/06/88)
In article <8085@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: ... >The response I received (was marked "Not an official X3J11 document"), >said that while "#define void char" might be better when it comes to pointers, >there were other cases where "#define void int" was better. Can anyone give a >concrete example? void blob() { ... } would become: int blob() { ... } instead of: char blob() { ... } Old C libraries commonly don't list the function return type to indicate a void but it really means int. The #define would retain compatibility with the old libraries. Anyone got better examples? -- Larry Cipriani, AT&T Network Systems and Ohio State University Domain: lvc@tut.cis.ohio-state.edu Path: ...!cbosgd!osu-cis!tut.cis.ohio-state.edu!lvc (strange but true)
ado@elsie.UUCP (Arthur David Olson) (06/06/88)
< < The response I received (was marked "Not an official X3J11 document"), < < said that while "#define void char" might be better when it comes to < < pointers, there were other cases where "#define void int" was better. < < Can anyone give a concrete example? < < . . .when compiling code such as < void func() { extern void exit(); /* ... */ } < . . .[u]sing char instead of int would not only gain nothing, but it would < introduce possible error (since in such an implementation, exit() would < probably be defaulted to return int). If someone could explain the error possibly being introduced here, I'd appreciate it. -- Market swaps ends for Chinese native. (5) ado@ncifcrf.gov ADO is a trademark of Ampex.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/07/88)
In article <8087@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes: >If someone could explain the error possibly being introduced here, >I'd appreciate it. "extern char exit();" is plain wrong on EVERYbody's system. Whether or not this causes a problem depends on the implementation. If a header is included that has e.g. "extern exit();" in it then there is a type clash, too. I just spent a whole (long) day hand-editing some C++ output C code sent to me from a system that had globally mapped "void" to "char". This was not a lot of fun, because some of the "char"s were correct and some weren't. In fact, most of them weren't. I had to study the context of each "char" to determine what to do. (I turned most of them back into "void" since the only problem with my compiler was lack of support for "void *".)
ado@elsie.UUCP (Arthur David Olson) (06/09/88)
> "extern char exit();" is plain wrong on EVERYbody's system. Whether > or not this causes a problem depends on the implementation. > If a header is included that has e.g. "extern exit();" in it > then there is a type clash, too. Thanks for the posting; these points should definitely help in improving my comment. Let's see if I can get some more help. Consider this code: ------------------------- extern void * malloc(); char * getten() { return malloc(10); } -------------------------- where this dumb function just returns a point to ten character's worth of allocated storage. Now if we #define void int as the standard suggests for backporting purposes, "old" compilers will happily compile the code without complaint--and on systems where (int *) != (char *), all hell will mysteriously break loose at runtime. In this case, if we #define void char the problem is avoided. So: are there any instances where a #define void char will introduce runtime problems (that is, cause "quiet changes") rather than causing compile-time problems ("noisy changes")? (Again, I'm interested in concrete examples.) -- Grocery swaps ends for Chinese native. (5) ado@ncifcrf.gov ADO is a trademark of Ampex.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/11/88)
I think this is a nonissue on which too much effort is being expended. The original example (#define void int) is just an illustration of why it MIGHT under SOME circumstances be USEFUL to be permitted to use #define to redefine keywords. NO redefinition of "void" is UNIVERSALLY proper. To take a specific case: Although I did not draft the part about "#define void int", my applications are prepared to do just that when the (non-ANSI) C compilation environment warrants, as it does on older 4BSD systems and on some microcomputer C implementations (those that do not provide the "void" extension to K&R [1st Edition] C). The specific mechanism I use is to include, in virtually EVERY application, a private header <std.h> that I set up once for each compilation environment. This defines a bunch of stuff the implementation of which varies from system to system but the use of which remains the same. Here is an extract of relevant portions of one implementation of <std.h>: typedef char *pointer; /* generic pointer (void *) */ #define const /* nothing */ /* (undefine for ANSI C) */ /* ANSI C definitions */ #ifndef EXIT_SUCCESS #define EXIT_SUCCESS 0 #endif #ifndef EXIT_FAILURE #define EXIT_FAILURE 1 #endif /* other kludges for deficient C implementations etc.: */ /*#define strchr index /* 7th Edition UNIX, 4.2BSD */ /*#define strrchr rindex /* 7th Edition UNIX, 4.2BSD */ /*#define void int /* K&R 1st Edition followers */ Notice the last line. I came up with this well before X3J11, and I have seen other programmers do the same. Notice also that my applications NEVER contain the "void *" that you worry about being broken by "#define void int"; instead I always use the generic "pointer" type for such pointers, and define it appropriately in this header. So in my situation, "#define void int" is sometimes useful, but "#define void char" never is (and can be harmful). There is certainly no need to change the X3J11 example.