Kai-Uwe Bux wrote:
[color=blue]
> Steven T. Hatton wrote:
>[color=green]
>> Kai-Uwe Bux wrote:[color=darkred]
>>> This description in turn might be given to me by a file that looks *as
>>> if* it was the header file foo.h actually substituted by the
>>> preprocessor.[/color]
>>
>> This is exactly my response to the situation.
>>[color=darkred]
>>> Now, this is just what I am doing to keep track of my small library. But
>>> it might provide an idea for the IDE that you are thinking about (I have
>>> followed a little bit of this discussion). Maybe, the IDE should not use
>>> the same include path as the compiler. It would derive its knowledge
>>> from fake haeders, ideally provided by library vendors as part of their
>>> documentation. (As far as the STL is concerned, there would be no need
>>> for different vendors to ship those fake headers as they would all have
>>> to agree anyway.[/color]
>>
>> There are at least two potential problems with that. First, if the
>> implementor doesn't exactly match the headers as presented in the
>> Standard, I will have to adjust my headers to match the implementation.[/color]
>
> Hm, if the implementation does not match the standard, I think you have a
> convincing case that the vendor should fix this.[/color]
Since, AFAIK, no implementation is 100% conformant, I assume their
non-compliance is something they would like to address themselves, but for
technical reasons have not found a way. Of course, I use products created
by people who strive to meed these standards.
[color=blue]
> You probably have a way better understanding of this after all the
> discussion that you have been through. I would like to know, what these
> circular dependencies are.[/color]
I haven't found time to study the matter much. But something seems amiss in
all of this.[color=blue]
> Or the
> vendor might resort to some macro magic to deal with this. An example
> could be, also I do not know if this is the case, identifiers like
> std::cout. This is a static object that can certainly be declared at most
> once.[/color]
Declared, or defined?
[color=blue]
> If several headers provide access to this identifier, it still
> cannot be defined in all of them.[/color]
If we are speaking of Standard Headers, I have to admit, I'm not completely
clear what is intended by such statements in the Standard as:
"The entities in the C++ Standard library are defined in headers, whose
contents are made available to a translation unit when it contains the
appropriate #include preprocessing directive (_cpp.include_)."
As I understand it, this is not the same usage as Stroustrup suggests for
headers. That is, headers should present an interface to the user, (or
implementor.). The Standard clearly speaks of entities being *defined* in
headers, and not simply declared in them.
[color=blue]
> For, what I have called "fake headers" that would not be a problem. Just
> document the identifier in both of them as including either one will make
> the identifier accessible to client code. Fake headers, as I use them,
> just provide information about which identifiers become visible by a
> certain include directive. That is their whole purpose on my hard disc.[/color]
I have to confess, I am a bit confused by all of this. If I have a library
with compiled code, I can use the declarations in the headers to compile my
source, and I don't need to know about the 'definitions' until I call the
linker. Or so I believe. I am under the impression that what the
declarations provide me with are the names needed to communicate to the
linker what needs to be connected to what. So if the declarations in your
"fake" headers have "real" names in the form that the declarations would
appear, I don't understand why they would not suffice as real headers to
feed to the compiler.
Stroustrup clearly provides a notion of having two (or more) sets of
functional headers. One set might be accessed by the user of a component,
while another would be accessed by its implementor. Perhaps I'm missing
something but it appears to me the Standard Library is not designed
according to the guidelines presented in TC++PL(SE).
[color=blue]
> I should stop speculating about the meaning of "circular dependencies" as
> I have to admit that I am not as deeply into this issue as to understand
> what experts might have refered to. At this point, it would certainly be
> helpful to have a concrete example of such a problem.[/color]
You can ask on the libstdc++ mailing list.
Interestingly the Standard says:
"A translation unit may include library headers in any order (_lex_).
Each may be included more than once, with no effect different from
being included exactly once, except that the effect of including
either <cassert> or <assert.h> depends each time on the lexically cur-
rent definition of NDEBUG.18)"
That seems to indicate that something is wrong with either the Standard, or
with the implementation.
[color=blue]
> I assume that the implemetation defined typedefs are bothering you? Now, I
> would like to know if it was really all that good if the user (or a smart
> IDE) would know or care about what these types are. Certainly, relying on
> that type being what it is in a particular implemetation will make your
> code non-portable. I would not want to know about this, and maybe I would
> not want my IDE to care about it either. Thus, I would suggest to
> introduce a special keyword implemetation_defined for the use in fake
> headers that makes it clear to everybody (including IDEs) that you are
> supposed *not* to know/care about this. Any programmer, who *really needs*
> to know will have to find out by himself. But, that might be a good thing.[/color]
I believe this reveals what I was saying about the failure of the Standard
Library to conform to the guidelines Stroustrup provides in TC++PL(SE).
There should be a user interface that hides such implementation details. I
have to ask what would go in my code to correspond to these
'implementation_defined' types.
[color=blue]
> Besides, there is the additional problem that an implementation defined
> type may not be a type expressible with the linguistic means of C++ at
> all. It could be just a placeholder for some magic going on within the
> compiler. Insisting that those types *must* be for real might come with a
> performance penalty in some situations. But I start speculating again, and
> I do not that much about compiler design as to asses whether this is
> really a problem.[/color]
I will need to study the matter more closely before I can comment.
[color=blue][color=green]
>> I'm really not sure what makes your "fake" headers "fake". Stroustrup
>> suggest there are situations in which your approach is applicable. Are
>> they accessed when the user's code is compiled?[/color]
>
> That is precisely what makes them "fake": the compiler does not get to see
> them at all. They are entirely for my own inspection. See, my C++ coding
> style is still not very mature, and I actually prefer to not declare but
> to define right away (sort of the Oberon style). Now, this makes the
> interface hard to comprehend as code gets in the way.[/color]
Stroustrup presents (at least)two rather distinct notions of something
called an interface. One is that which I have described involving the use
of header files. The other is the use of abstract base classes as
interfaces.
[color=blue]
> Thus, I create a
> second file with all definitions turned into declarations and all the code
> removed. Only the comments describing what the routines do are preserved.
> Also some internal stuff, like private fields or helper classes that had
> to be put in namespace level and could not be hidden are left out of the
> fake headers if they are supposed to be off limits for client code. This
> file, the fake header, is for my eyes only![/color]
I reiterate my questions about their 'fake' nature.
[color=blue]
> have not really thought about the problems one faces in designing an IDE.
> If it is your informed engineering opinion that IDE and compiler need to
> access identical information, you may be right. Certainly, I am not the
> one to prove you wrong on this account.[/color]
Oh, no. I'm not the expert. But my instincts tell me it's best to have the
interface representing the Standard Libraries created in conjunction with
the implementation, and indeed, they should be the source of the
declarations used by the compiler.
I have had to refine my thinking in this regard. I believe I've actually
discussed this before in a different context on comp.std.c++. It's ironic
that people such as Stroustrup and Josuttis express opinions such as 'there
is much room for improvement' or 'the design is far from perfect', while
people who have far less personal investment in the design are overtly
hostile to critics of the current design.
There are some historical reasons that might explain their defensiveness,
however. For example, the critique by Ian Joyner probably did more to
prevent a reasonable assessment of C++ than it did to provide one. I
haven't read the whole thing, mostly because of the excesses in the parts I
have read. The fact he managed to get 10 paragraphs out of the goto
statement exemplifies this.
Stroustrup's treatmet of the goto was something on the order of. It's
there. There's little reason to ever use it.
Here's a bit of irony:
$ pwd
/usr/src/linux/kernel
Fri Jun 11 01:49:59:> grep goto *.c | wc -l
226
$ cd /download/edu/stanford/cweb
$ grep goto *.c | wc -l
37
$ grep Copyright README
% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop:
http://www.kdevelop.org SuSE:
http://www.suse.com
Mozilla:
http://www.mozilla.org