newman@athena.mit.edu (Ron Newman) (12/10/87)
Many header files begin with something like #ifndef __SOME_UNUSUAL_NAME__ #define __SOME_UNUSUAL_NAME__ and end with #endif so that if you #include the file more than once, nothing bad happens. Why not change the semantics of "#include" to be: "if, while processing the current .c source file, I have already included this file once, then don't include it again"? That seems a lot cleaner than having to (remember to) put the #ifndef stuff into every header file. It would also eliminate problems with vendors who forget to do this to their standard header files. Is it too late to fix this for ANSI C?? /Ron Newman MIT Project Athena
tim@doug.UUCP (Tim J Ihde) (12/10/87)
In article <2000@bloom-beacon.MIT.EDU>, newman@athena.mit.edu (Ron Newman) writes: > Why not change the semantics of "#include" to be: "if, while > processing the current .c source file, I have already included this > file once, then don't include it again"? I don't know if this is in the ANSI definition of include or not, but this is exactly how the latest version of cpp on System V works. It simply remembers each include file that it has read and will ignore it if the same file shows up again. This is definatly the way to go. tim -- Tim J. Ihde ihnp4!ctsmain!doug!tim (201) 535-9897 Ok, we can all agree that this is my fault.
rlk@think.COM (Robert Krawitz) (12/10/87)
In article <2000@bloom-beacon.MIT.EDU> newman@athena.mit.edu (Ron Newman) writes:
]Many header files begin with something like
]
] #ifndef __SOME_UNUSUAL_NAME__
] #define __SOME_UNUSUAL_NAME__
]
]and end with
]
] #endif
]
]so that if you #include the file more than once, nothing bad happens.
]
]Why not change the semantics of "#include" to be: "if, while
]processing the current .c source file, I have already included this
]file once, then don't include it again"?
1) The same file may have multiple names (symlinks and/or hard
links). How do you KNOW whether a file has been included? The only
way is by defining an attribute that only that file will have. The
easiest way to do this (aside from checking device/inumbers, which is
not portable and may not work in some bizarre cases, or other system
dependent hacks) is to #define a unique name.
2) There may be equivalent files (e. g. I may have my own version of
something-unusual.h that I want instead of the system version) and I
want to make sure the system version doesn't overload mine.
3) Sometimes it may be DESIRED to include the same file multiple times.
]That seems a lot cleaner than having to (remember to) put the #ifndef
]stuff into every header file. It would also eliminate problems with
]vendors who forget to do this to their standard header files.
]Is it too late to fix this for ANSI C??
Vendors who don't do this should fix their files, just like any other
broken code. Users who don't remember to do this will get screwed,
then they will learn, just like they remember not to dereference null
pointers the first time they don't use a VAX. Artificial constraints
like this to try to recover from simple programming errors just make
compilers more complicated and bug-prone, and prevent the programmer
from deliberately doing something which may be unobvious but useful.
harvard >>>>>> |
bloom-beacon > |think!rlk Robert Krawitz <rlk@think.com>
ihnp4 >>>>>>>> .
jss@hector.UUCP (Jerry Schwarz) (12/11/87)
In article <2000@bloom-beacon.MIT.EDU> newman@athena.mit.edu (Ron Newman) writes: > >Why not change the semantics of "#include" to be: "if, while >processing the current .c source file, I have already included this >file once, then don't include it again"? > We have such a cpp here and it has certain advantages. But the problem with putting such a rule into the standard is you then have to define "same file". Can <foo.h> be same as "foo.h". Suppose that because of -I options <foo.h> and <sys/foo.h> resolve to the same file. Even worse, suppose "d/foo.h" contains a #include of "g.h" is this the same as "d/g.h". You can punt and say that it is up to the implementor (as the committee has done for where to find "foo.h"). But then have you gained much by adding the rule to the standard. >Is it too late to fix this for ANSI C?? Almost certainly. I get a sense that many readers of this group do not understand how far along the ANSI standard is. The committee has been working three or four years. The draft standard is about to go out for its second public review. It now takes a two thirds vote of the committee to make a change. (Some proposals have won majorities recently but failed because of the 2/3 rule.) Any significant change will require another public review process. Proposals such as the above or "0b", whatever their merits, are just too late. If you want a change you probably have to show not just that your change is a good idea, but that there is a critical flaw in the way the current standard addresses whatever area you are concerned with. Uglyness, while a flaw, will not count as a critical flaw in this context. A contradiction in the proposed standard might. Jerry Schwarz Bell Labs Not a member of X3J11
riddle@woton.UUCP (Prentiss Riddle ) (12/11/87)
newman@athena.mit.edu (Ron Newman) writes: > Why not change the semantics of "#include" to be: "if, while > processing the current .c source file, I have already included this > file once, then don't include it again"? But sometimes you *want* to #include a file multiple times. One example that comes to mind is the problem of generating essentially the same code for multiple types of objects. Redefine a few identifiers or macros before each #inclusion and you've got it. One example of a program that does this trick is c_config, posted to the net some time back by Steve Pemberton (steve@cwi.nl). --- Prentiss Riddle ("Aprendiz de todo, maestro de nada.") --- Opinions expressed are not necessarily those of Shriners Burns Institute. --- riddle@woton.UUCP {ihnp4,harvard}!ut-sally!im4u!woton!riddle
robert@pvab.UUCP (Robert Claeson) (12/11/87)
In article <13395@think.UUCP> rlk@THINK.COM writes: >1) The same file may have multiple names (symlinks and/or hard >links). How do you KNOW whether a file has been included? The only >way is by defining an attribute that only that file will have. The >easiest way to do this (aside from checking device/inumbers, which is >not portable and may not work in some bizarre cases, or other system >dependent hacks) is to #define a unique name. How can you be sure that the name you choose is unique, especially if you use links or symlinks? -- Robert Claeson, System Administrator, PVAB, Box 4040, S-171 04 Solna, Sweden eunet: robert@pvab uucp: sun!enea!pvab!robert
ericb@athertn.Atherton.COM (Eric Black) (12/12/87)
In article <13395@think.UUCP> rlk@THINK.COM (Robert Krawitz) writes: >In article <2000@bloom-beacon.MIT.EDU> newman@athena.mit.edu (Ron Newman) writes: >]Why not change the semantics of "#include" to be: "if, while >]processing the current .c source file, I have already included this >]file once, then don't include it again"? Because it would be a bad idea. Robert gives a few good reasons: >1) The same file may have multiple names (symlinks and/or hard links). And NFS-style mounts that give other aliasing possibilities (we do that a lot here). And, as Jerry Schwarz (and others) pointed out, the various combinations of <file>, "file", and either form with directory names prepended along with various -Idir cpp options makes it pretty hard to tell when it's the "same file". It can be even harder for nested #includes (no religious wars, please!). >2) There may be equivalent files We have that case here. When CPP or the compiler barf because of a redefinition caused by including two variants of a header file when only one should have been, the error messages given to the programmer are sometimes less than clear. In such cases, we can have the #ifdef A_VARIANT_HAS_ALREADY_BEEN_INCLUDED clause provoke a real syntax error, such as: #ifdef SS_SUBSYSTEM_VARIANT_DEFINED !?!?!?!? More meaningful message, which the programmer can find when he edits this "standard" foo.h file to see why it got a syntax error #else #define SS_SUBSYSTEM_VARIANT_DEFINED /* continue with the definitions #endif SS_SUBSYSTEM_VARIANT_DEFINED Of course, we can nest the two techniques, to allow harmless re-inclusion of the one file while still catching the erroneous inclusion of a second mutually-exclusive variant. >3) Sometimes it may be DESIRED to include the same file multiple times. Yes, Virginia, you may want to have something like "recursive" header files, where on subsequent inclusions some symbols are re-defined, or un-defined. This could certainly be done with separate files, but then you have two files to maintain, and if you are changing symbol definitions it's a lot easier to coordinate and keep them consistent if they are in one file with lots of comments, rather than two. >Artificial constraints >like this to try to recover from simple programming errors just make >compilers more complicated and bug-prone, and prevent the programmer >from deliberately doing something which may be unobvious but useful. We all know that one technique for helping the compiler to warn the programmer about a "=" where he really meant "==" (like in "if (a = 1)") is to get into the habit of coding it as "if (1 == a)"; then if you blow it the compiler can complain. That doesn't mean that we want the compiler to silently disallow my coding it the first way! -- Eric Black "Garbage in, Gospel out" UUCP: {sun!sunncal,hpda}!athertn!ericb Domainist: ericb@Atherton.COM
daveb@laidbak.UUCP (Dave Burton) (12/13/87)
In article <1011@woton.UUCP> riddle@woton.UUCP (Prentiss Riddle ) writes: >newman@athena.mit.edu (Ron Newman) writes: >> Why not change the semantics of "#include" to be: "if, while >> processing the current .c source file, I have already included this >> file once, then don't include it again"? > >But sometimes you *want* to #include a file multiple times. ... ... I missed the first part of this exchange, so pardon me if I'm out-of-context. Why change the semantics of #include anyway? Using the following technique, you can make #include behave in both ways: #ifndef HEADER_H #define HEADER_H 1.0 /* version number, or nothing */ #define X #define Y #define Z #endif /* HEADER_H */ By enclosing the entire header file within the #ifndef/#endif pair (or just the critical portion), the header may be included several times without problem. -- --------------------"Well, it looked good when I wrote it"--------------------- Verbal: Dave Burton Net: ...!ihnp4!laidbak!daveb V-MAIL: (312) 505-9100 x325 USSnail: 1901 N. Naper Blvd. #include <disclaimer.h> Naperville, IL 60540
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/13/87)
In article <2000@bloom-beacon.MIT.EDU> newman@athena.mit.edu (Ron Newman) writes: >Why not change the semantics of "#include" to be: "if, while >processing the current .c source file, I have already included this >file once, then don't include it again"? Because that's not the way C has worked, and some of us use this capability. It was proposed at an X3J11 meeting and trounced.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/13/87)
In article <385@doug.UUCP> tim@doug.UUCP (Tim J Ihde) writes:
-I don't know if this is in the ANSI definition of include or not, but this
-is exactly how the latest version of cpp on System V works. It simply
-remembers each include file that it has read and will ignore it if the same
-file shows up again. This is definatly the way to go.
It definitely is NOT the way to go, and they're going to have to fix it
before they can be ANSI conformant.
tim@doug.UUCP (Tim J Ihde) (12/14/87)
In article <6809@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > In article <385@doug.UUCP> tim@doug.UUCP (Tim J Ihde) writes: > -It simply > -remembers each include file that it has read and will ignore it if the same > -file shows up again. This is definatly the way to go. > > It definitely is NOT the way to go, and they're going to have to fix it > before they can be ANSI conformant. After reading some of the other responses to the initial article, I tend to agree with you; although this facility is quite helpful in cases where you are dealing with standard include files that do not have a line like #define CTYPEH or whatever. Anyway, in the interum I obtained a copy of the manual page for this version of cpp. It lists a #pragma statement as follows: #pragma multiple Allows the current file to be included more than once. The default action nomultiple causes each #include file to be included only once. So in the true C style, it will allow people who know what they are doing (or think they do) to go ahead and do it. I assume that the reason they did not make the standard functionality (ie multiple includes) the default was because this would not have helped in cases such as with <ctype.h>. I think I would have preferred for them to fix these include files instead of breaking with the standard. I also noticed a -I- option to the preprocessor, indicating that -I<dir> listed directories appearing BEFORE the -I- in the command line are searched only for "" included files, whereas and -I<dir> directories listed AFTER the -I- are searched for either "" or <> included files. Nmake generates command lines using this format. This might get around the problem of include files with the same names if used carefully, but again this is non-standard. tim -- Tim J. Ihde ihnp4!ctsmain!doug!tim (201) 535-9897 Ok, we can all agree that this is my fault.
gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/15/87)
In article <339@pvab.UUCP> robert@pvab.UUCP (Robert Claeson) writes: -In article <13395@think.UUCP> rlk@THINK.COM writes: ->1) The same file may have multiple names (symlinks and/or hard ->links). How do you KNOW whether a file has been included? The only ->way is by defining an attribute that only that file will have. The ->easiest way to do this (aside from checking device/inumbers, which is ->not portable and may not work in some bizarre cases, or other system ->dependent hacks) is to #define a unique name. - -How can you be sure that the name you choose is unique, especially if -you use links or symlinks? That was rlk's whole point; only the file contents (in particular the unique #define) can be IMMUNE to links and symlinks. #ifndef UNIQUE_SYMBOL #define UNIQUE_SYMBOL /* useful definitions & declarations here */ #endif
hansen@pegasus.UUCP (Tony L. Hansen) (12/21/87)
< From: tim@doug.UUCP (Tim J Ihde)
<
< In article <2000@bloom-beacon.MIT.EDU>, newman@athena.mit.edu (Ron Newman) writes:
< > Why not change the semantics of "#include" to be: "if, while
< > processing the current .c source file, I have already included this
< > file once, then don't include it again"?
<
< I don't know if this is in the ANSI definition of include or not, but this
< is exactly how the latest version of cpp on System V works. It simply
< remembers each include file that it has read and will ignore it if the same
< file shows up again. This is definatly the way to go.
(I hadn't seen anything else come back yet on the net refuting this.)
The latest distributed System V version of CPP does NOT do this automatic
checking for multiple #includes of a file. The author of the above article
had installed nmake on his machine, which comes with its own version of CPP,
but hadn't realized that CPP had changed.
Tony Hansen
ihnp4!pegasus!hansen, attmail!tony
ark@alice.UUCP (12/22/87)
The trouble with changing the meaning of #include is that it is sure to break some programs. Instead, how about this: #include {x} #include 'x' Saying {x} is like saying <x> except that you only want x once. Saying 'x' is like saying "x" except that you only want x once.