gwu@tixdemo.tcs.com (George Wu) (01/23/91)
In article <15917@reed.UUCP>, minar@reed.bitnet (Nelson Minar,L08,x640,7776519) writes: |> |> In C, I barely managed to keep all my header files straight and organized. |> C++ just compounds my problems. |> |> main.C is what you would expect. In the process of doing its thing, |> it creates an instance of LineWindow and an instance of Turtle. |> Therefore, it includes the files lineWindow.h and turtle.h |> |> lineWindow.C has to include lineWindow.h, obviously, and turtle.C includes |> turtle.h. |> |> The problem is, one of the member variables in class ScreenTurtle is a |> reference to an instance of LineWindow. Therefore, the header turtle.h |> must also include lineWindow.h for the class declaration. |> |> So, when one goes to compile main.C, it includes lineWindow.h and then |> later includes turtle.h which again includes lineWindow.h. Unless I take |> precautions (either a '#pragma once' or a series of '#ifndef .. #define') |> the header is included twice, and class LineWindow is declared twice, and |> the compiler gets annoyed. If ScreenTurtle has a member variable *pointing* to an instance of a LineWindow, then it doesn't need to include lineWindow.h. You can just add class LineWindow; to lineWindow.h. It's sort of like a function extern declaration for externally defined classes. You also might be able to do this with a reference, but I'm not sure. Try it, and if it doesn't work, switch to a pointer. (Yeah, I know, some people prefer references to explicit pointers.) |> Are constructs like '#pragma once' just entirely common in C++ headers? I |> find them ugly.. We've never used a #pragma, and we've got hundreds of thousands of lines of code. We do use the #ifndef X, #define X, /* declarations */, #endif to surround the contents of all header files, though. George ---- George J Wu | gwu@tcs.com or uunet!tcs!gwu Software Engineer | 2121 Allston Way, Berkeley, CA, 94704 Teknekron Communications Systems, Inc.| (415) 649-3752
chip@tct.uucp (Chip Salzenberg) (01/24/91)
According to minar@reed.bitnet (Nelson Minar,L08,x640,7776519): >Unless I take precautions (either a '#pragma once' or a series of >'#ifndef .. #define' the header is included twice ... I routinely protect all my header files (C and C++) with both "#ifndef FOO_H ... #define FOO_H ... #endif" and "#pragma once". I also add "#ifdef __cplusplus ... extern "C" { ... #endif" and the closing "}" to all my C header files. It ain't pretty, but it avoids lots of headaches down the road. -- Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> "If Usenet exists, then what is its mailing address?" -- me "c/o The Daily Planet, Metropolis." -- Jeff Daiell
lerman@stpstn.UUCP (Ken Lerman) (01/30/91)
In article <15917@reed.UUCP> minar@reed.bitnet (Nelson Minar,L08,x640,7776519) writes:
:
:In C, I barely managed to keep all my header files straight and organized.
:C++ just compounds my problems.
...
:
:Are constructs like '#pragma once' just entirely common in C++ headers? I
:find them ugly..
Objective-C (please hold the flames down to a dull roar) uses '#import
<foo.h>' to mean the same thing as '#include <foo.h>' except do
nothing if the file has already been imported. This is MUCH nicer
than '#pragma once' and might be a useful addition to C++.
Ken
bertrand@eiffel.UUCP (Bertrand Meyer) (01/31/91)
From <6107@stpstn.UUCP> by lerman@stpstn.UUCP (Ken Lerman): > In article <15917@reed.UUCP> minar@reed.bitnet > (Nelson Minar,L08,x640,7776519) writes: > : > :In C, I barely managed to keep all my header files > straight and organized. > :C++ just compounds my problems. > ... > Objective-C (please hold the flames down to a dull roar) uses '#import > <foo.h>' to mean the same thing as '#include <foo.h>' except do > nothing if the file has already been imported. This is MUCH nicer > than '#pragma once' and might be a useful addition to C++. For that matter, with Eiffel there is no need for header files or make files of any kind. The compiler takes care of analyzing dependencies (by analyzing the source text, which is where the information is, and the only place where it should be) and deciding what it needs to recompile. Of course, the language was designed to make this possible. Isn't it time for the software profession to move to the nineteen-nineties? -- Bertrand Meyer bertrand@eiffel.com
sabbagh@acf5.NYU.EDU (sabbagh) (02/01/91)
bertrand@eiffel.UUCP (Bertrand Meyer) writes: > For that matter, with Eiffel there is no need for header files >or make files of any kind. The compiler takes care of analyzing >dependencies (by analyzing the source text, which is where the >information is, and the only place where it should be) and deciding >what it needs to recompile. Of course, the language was designed >to make this possible. > Isn't it time for the software profession to move to the >nineteen-nineties? >-- Bertrand Meyer >bertrand@eiffel.com Unfortuantely, Dr. Meyer has committed the one great sin of academia: he has become religious about a single idea. Here's why the software profession can't move to the 1990's: 1. Eiffel isn't available on micros; C++ is. 2. Eiffel is supported by only one vendor (2 since Abajton licensed it to port to Mac; who knows when this will happen?). 3. Eiffel is a GREAT IDEA IN THEORY; major obstacles exist to implementing a lot of its great features. 4. There is far more experience with C++ on real projects than with Eiffel. Hadil G. Sabbagh E-mail: sabbagh@cs.nyu.edu Voice: (212) 998-3125 Snail: Courant Institute of Math. Sci. 251 Mercer St. New York,NY 10012 "The difference between theory and practice in practice is always greater than the difference between theory and practice in theory." - Anon. Disclaimer: This is not a disclaimer.
chased@rbbb.Eng.Sun.COM (David Chase) (02/01/91)
In article <1466@acf5.NYU.EDU> sabbagh@acf5.NYU.EDU (sabbagh) writes: >bertrand@eiffel.UUCP (Bertrand Meyer) writes: > >> For that matter, with Eiffel there is no need for header files >>or make files of any kind. The compiler takes care of analyzing >>dependencies (by analyzing the source text, which is where the >>information is, and the only place where it should be) ... >Unfortuantely, Dr. Meyer has committed the one great sin of academia: he >has become religious about a single idea. Here's why the software profession >can't move to the 1990's: > [remarks directed against Eiffel deleted] I think you have missed the point; these features need not be unique to Eiffel. Granted, Meyer takes a more extreme position (analyze the source text) than I do, but "header files" that are something merged into the source text by a pre-processor are really not a very good idea. Separate interface files in the style of Mesa and Modula are much more useful. They permit easy design and implementation of language-based tools that (in C, at least) are usually handled by creation of yet-another meta-language (for example, Mig). Makefiles are unnecessary. Data marshalling routines can be created by a language-based tool. (One can decide, after the fact -- "hey, I'd like to store this data, pointers and all, on disk", and get the job done by using a simple tool, instead of having to write a meta-language description of the existing data structures for processing by some other tool.) Stub generators are another language-based tool. I'm not saying that these things are imposible for C/C++, but for an interface-based language they are far far easier. In C++, people I know have complained about multiple copies of virtual function tables created by declarations included in multiple files, and have proposed a pragma to deal with this. For a language with designed-in "interface" files, no such problem exists (rather, it is up to the implementation to deal with this). For C++, pre-compiled header files are regarded as a new and interesting problem to be tackled; for Mesa, Modula, and their derivatives, this problem has been solved for years. Other approaches include compiler servers that cache interface files for re-use. I suppose I'm preaching to the unconvertable, but it seems unusual that someone would damn a language feature that they haven't tried. I've tried both, and I know which one I like better. Note, too, that in the system I used (Modula-3) we did make use of the pre-processor from time to time, but only for those things where it was the most appropriate tool (e.g., OS-dependent changes to data structures, not simulating interfaces by file inclusion). We had a stub generator, a data marshalling generator, a makefile generator (because we didn't really feel like duplicating the entire function of make), a compiler server (that cached interface files for subsequent compiles), consistency checkers, a C-generating compiler, and an interpreter. We used our tools to build new tools, and we were very productive. David Chase Sun (all the Modula-3 work took place at Olivetti over a period of about 2 years)
chip@tct.uucp (Chip Salzenberg) (02/01/91)
According to bertrand@eiffel.UUCP (Bertrand Meyer): >Isn't it time for the software profession to move to the >nineteen-nineties? Don't look down your nose at textual inclusion. It has other uses besides the common "#include <class.h>". -- Chip Salzenberg at Teltronics/TCT <chip@tct.uucp>, <uunet!pdn!tct!chip> "I want to mention that my opinions whether real or not are MY opinions." -- the inevitable William "Billy" Steinmetz
bertrand@eiffel.UUCP (Bertrand Meyer) (02/01/91)
1 - - - - - - From <7091@exodus.Eng.Sun.COM> by chased@rbbb.Eng.Sun.COM (David Chase): > I think you [i.e. Hadil G. Sabbagh] have missed [B. Meyer's] point; > these features [no need for make files, header files etc.] > need not be unique to Eiffel. Mr. Chase is quite correct. He mentions Mesa and Modula-3, and I have no doubt that automatic dependency analysis can be implemented in these languages. Another language for which I have seen programming environments which perform similar work is Ada. A full-fledged object-oriented language does make the problem more challenging technically (because of multiple and repeated inheritance, cycles in the client relation etc.). The point of my message was that for automatic dependency analysis to work the language design has to make it possible. This is true for Ada, Eiffel, Mesa and (from the looks of it) Modula-3. There are undoubtedly other examples. 2 - - - - - - - My message discussed a specific point (header files), mentioning Eiffel in response to a message mentioning Objective-C. Mr. Sabbagh used this opportunity to include general comments about Eiffel which are more political than technical, and not connected to the matter of header files. Let it be registered that I do not intend to help start a general political Eiffel-C++ debate. However I do need to correct the inaccuracies regarding Eiffel in Mr. Sabbagh's four points: >> 1. Eiffel isn't available on micros; C++ is. >> 2. Eiffel is supported by only one vendor (2 since Abajton licensed it to port to Mac; who knows when this will happen?). Eiffel is available on micros under Unix, although it is true that no MS-DOS implementation is available yet. However an independent DOS implementation, by a German company, has been announced and will be demonstrated at CeBIT in March. I saw an early version in October and was quite impressed. We know of several other ongoing independent efforts. > 3. Eiffel is a GREAT IDEA IN THEORY; major obstacles exist to > implementing a lot of its great features. What does this mean? All of Eiffel features have been implemented and are being used since 1986 by thousands of people worldwide. Please don't propagate the ``it's like Algol 60'' myth. > 4. There is far more experience with C++ on real projects than with > Eiffel. There are certainly more people using C++ today, although there is more Eiffel usage than one would think by reading only the current technical press. In the absence of scientifically collected evidence, however, there are good reasons to believe that the body of actual object-oriented development experience (significant projects using O-O methodology, as opposed to small experiments, or just C programming labelled C++) is at least as strong on the Eiffel side. To close, the following bears repeating: my only intent in the second part of this message is to correct inaccuracies, not to waste any more of anyone's time on non-technical language comparisons. -- -- Bertrand Meyer bertrand@eiffel.com
mat@mole-end.UUCP (Mark A Terribile) (02/03/91)
> >> For that matter, with Eiffel there is no need for header files > >>or make files of any kind. The compiler takes care of analyzing > >>dependencies (by analyzing the source text, which is where the > >>information is, and the only place where it should be) ... > >Unfortuantely, Dr. Meyer has committed the one great sin of academia: he > >has become religious about a single idea. ... > I think you have missed the point; these features need not be unique > to Eiffel. Granted, Meyer takes a more extreme position (analyze the > source text) than I do, but "header files" that are something merged > into the source text by a pre-processor are really not a very good > idea. Separate interface files in the style of Mesa and Modula are > much more useful. ... All of this requires that the programming language also specify the programming environment. It also means that things that are built for the language can be used for nothing else. Is there a YACC or bison for Eiffel? Can the `real' source be managed by the same mechanism that manages dependencies over the Eiffel? There are good reasons for not building the environment into the language; the tendency to circumscribe the language is one of them. As far as making interface seperate from the specification of the type: That messes up such things as inline functions, or else it requires that the symbol resolution (first part of linking) be done BEFORE code generation. It would be nice to have that capability, but most programming environments do not support it, and you need the support of the environment if you want to be sure that native code which you generate will be accepted by that environment. I agree that things could be better. It might even be possible to incorporate better things into C. But not everything that does the gee-whizbang thing you think you want is really better. > I suppose I'm preaching to the unconvertable, but it seems unusual > that someone would damn a language feature that they haven't tried. > I've tried both, and I know which one I like better. Well, there are some things to which *I* can be converted, and there are others to which I cannot be converted. Hot-shot environments that are so smart I can't make them smarter on my terms are one thing that I will do without, thank you. > Note, too, that in the system I used (Modula-3) we did make use of the > pre-processor from time to time, but only for those things where it > was the most appropriate tool (e.g., OS-dependent changes to data > structures, not simulating interfaces by file inclusion). We had a > stub generator, a data marshalling generator, a makefile generator > (because we didn't really feel like duplicating the entire function of > make), a compiler server (that cached interface files for subsequent > compiles), consistency checkers, a C-generating compiler, and an > interpreter. We used our tools to build new tools, and we were very > productive. All well and good ... but in a circumscribed environment you couldn't have done any of them. Dependency generators for Make on C and C++ are rather trivial, especially on the Sun but also on other systems; all you have to do is needle the preprocessor. A few lines of ksh will do the job. -- (This man's opinions are his own.) From mole-end Mark Terribile
rfg@NCD.COM (Ron Guilmette) (02/05/91)
In article <6107@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes: > >Objective-C (please hold the flames down to a dull roar) uses '#import ><foo.h>' to mean the same thing as '#include <foo.h>' except do >nothing if the file has already been imported. This is MUCH nicer >than '#pragma once' and might be a useful addition to C++. Contrary to Ken's misguided opinions, #import is *not* much nicer than #pragma once. Quite the contrary, it is much stupider. Consider this. I have an include file which should only be included at most one time during an entire compilation. If it gets included more than once then I'll get errors. Now ask yourself this one question. Is the fact that this file must only be included once into an entire compilation a property of the include file in question, or is it a property of all of the files which include the include file in question? Quite obviously, the "must only be included once" property is a property of the "includee". It is *not* a property of all of the "includers". This special property should therefore be expressed by having something special coded into the (one and only) "includee". That way, if the includee changes with respect to this one property, you can just change the text of the includee and leave the text of all of the includers alone. It's painfully obvious that Stepstone got it bass-ackwards in Objective-C (with their #import directive). I guess that their existing customer base is either too large or too stagnant to permit them to to recognize their mistake and to convert over to using #pragma once. Either that or else they have a bad case of `Not Invented Here' syndrome. Also note that `#pragma once' is likely to be portable to all existing ANSI C environments because ANSI C requires that ANSI C preprocessors *must* ignore all #pragmas that they do not understand. Most ANSI C compiler will totally barf on #import however, and the ANSI C standard gives them full permission to do so. -- // Ron Guilmette - C++ Entomologist // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // Motto: If it sticks, force it. If it breaks, it needed replacing anyway.
steve@taumet.com (Stephen Clamage) (02/06/91)
rfg@NCD.COM (Ron Guilmette) writes: >Also note that `#pragma once' is likely to be portable to all existing >ANSI C environments because ANSI C requires that ANSI C preprocessors >*must* ignore all #pragmas that they do not understand. Well, it's portable only in the degenerate sense that a compiler won't complain if it doesn't recognize #pragma once. It might merely do something unintended and possibly harmful. Consider these cases: 1. The file must not be included more than once but #pragma once is ignored. 2. #pragma once means something entirely different to a particular compiler (such as turn on Customer Engineer features, which can be turned off with #pragma offce). If you want to port programs to different environments, don't rely on nonstandard features. -- Steve Clamage, TauMetric Corp, steve@taumet.com
benson@odi.com (Benson I. Margulies) (02/06/91)
In article <3707@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >In article <6107@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes: >> >>Objective-C (please hold the flames down to a dull roar) uses '#import >><foo.h>' to mean the same thing as '#include <foo.h>' except do >>nothing if the file has already been imported. This is MUCH nicer >>than '#pragma once' and might be a useful addition to C++. > >Contrary to Ken's misguided opinions, #import is *not* much nicer than >#pragma once. Quite the contrary, it is much stupider. > >Consider this. I have an include file which should only be included >at most one time during an entire compilation. If it gets included >more than once then I'll get errors. Give me any include file, and I believe that I can surround it with enough {} and #defines to make it safely includable a second time. It is a traditional unix vice to build things that only work one at a time. e.g. dbm. -- Benson I. Margulies
jimad@microsoft.UUCP (Jim ADCOCK) (02/06/91)
In article <6107@stpstn.UUCP> lerman@stpstn.UUCP (Ken Lerman) writes: |In article <15917@reed.UUCP> minar@reed.bitnet (Nelson Minar,L08,x640,7776519) writes: |: |:In C, I barely managed to keep all my header files straight and organized. |:C++ just compounds my problems. | |... | |: |:Are constructs like '#pragma once' just entirely common in C++ headers? I |:find them ugly.. | |Objective-C (please hold the flames down to a dull roar) uses '#import |<foo.h>' to mean the same thing as '#include <foo.h>' except do |nothing if the file has already been imported. This is MUCH nicer |than '#pragma once' and might be a useful addition to C++. I agree. I think its silly that the most common [and unavoidable] use of the preprocessor requires several lines of code to program. Likewise, one could imagine an: #export "foo.h" .... #endexport directive that [in the simplest implementations] would have the effect of copying the code found in the enclosed section, before macro expansion, to the file "foo.h" Such an export section would allow one write a complete class in one .c file, with the required .h file generated "automatically." Smarter implementations could only generate a new .h section if the .c export section changed, could cache the #export section in memory, ....