From: jimad@microsoft.com (Jim Adcock)
Subject: Re: Standard library functions and macros
Date: 04 Jan 93 22:46:04 GMT
Organization: Microsoft Corporation

In article <9300302.725@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON) writes:
|I would be surprised if the changes did not require "real" external functions
|"shadowing" the inline definitions just as ANSI C required real functions
|to shadow macro definitions. 

It wouldn't be a conforming implementation if it provided both inline
and out-of-line implementation of a function.  That would violate
the one-definition rule.

|I think that perhaps you are overreacting a
|little, Jim. 

That depends on one's point of view.  If one truly claims that ANSI-C
is a base doc for the ANSI-C++ effort, then I don't think I'm overreacting
when the ANSI-C++ committee redefines how the ANSI-C libraries work without
having a conflicting overriding definition in the ARM.  If ANSI-C and ARM
conflict, then by all means follow ARM, or otherwise resolve the conflict.
But to ignore one of the base docs when no conflicts exist is to make
a mockary of calling the thing a base doc.  There's a lot of good work
in the ANSI-C base document, a lot of things have been well-defined in
the ANSI-C that aren't defined at all in the ARM, and I'm afraid people are
ignoring the ANSI-C work simply for the sake of N.I.H.  Which would be sad.

Whether I'm overreacting or not also depends on whether people consider
it important to get programmers to switch from C to C++.  Every obstacle
you put in their way gives them one more excuse to stay with C.  One
obvious excuse is if C compiles their existing code more efficiently
that C++.  Macros and intrinsics can still typically beat inlines.
Another excuse is if they use 3rd party C libraries that are now 
deemed incompatible with "standard" C++.

|>|If Jim is saying that in a particular implementation the #undef has
|>|this effect and believes that effect should be preserved, then nothing
|>|stops an implementation from giving the #undef the same effect in C++,
|>|although I suspect he will have to lobby his vendors very hard to
|>|convince them to implement such a feature.
|>
|>If this is possible, then show me how to do it, because the solution
|>is not obvious to me.
|
|Step 1. Introduce a #pragma no-inline, eg.
|
|	#pragma no-inline putchar	// don't inline any function
|					// called putchar
|
|This should not pose much implementation difficulty.
|(Many compilers already allow a #pragma which has the same effect but
|works on all inline functions, rather than a particular one at a time.)
|
|Step 2. Ensure that if foo is not a macro, then
|	#undef foo
|has the same effect as
|	#pragma no-inline foo
|This should be even easier to implement.

Your "solution" does not implement the semantics called out in the ANSI-C
spec.  If you read the ANSI-C spec, you will find other requirements on
the ANSI-C library implementation that your "solution" does not support,
such as selectively allowing out-of-line implementation on a per-function-call
basis simply by enclosing the function name in parenthesis:

	(putchar)('\n');

|In the first case, the name would only be reserved
|for use as an external identifier. Programmers could still use that
|name for member functions, for example.

With only a handful of plausible exceptions, ANSI-C standard functions
have "NO" applicability as member function names because they are
*decorated* names.  If you want to make selective argument that some of
the few non-decorated ANSI-C standard function names are so attractive
that they ought to be returned to the programmer name space, so that
these few exceptional, undecorated standard function names could be used
as member functions, THEN I would agree with you.  I just don't buy the
blanket argument that ALL the standard C functions ought to be returned
to the programmer name space.  Because the vast majority of the standard
function names are *decorated* -- as in fputc means "file-put-character"
and such manually mangled names have no reasonable use to C++ programmers
as member function names in any case.

As an example of a standard C function name that is so "attractive" that
it out to be returned to C++ programmer space consider "free".  This name
should have never been taken by the standard library in the first place.
It should have been a decorated name, such a "mfree" to make it symmetric
with the decorated malloc "memory-allocate" routine.  So if you 
want to selectively argue that a few of the standard-C functions should require
implementation as inlines so as to not take the whole name space away
from the programmer, then I agree.  All standard C functions in this
category?  No way!  Functions such as fputc would be very highly silly
member functions!

|I disagree. The pure namespace generally occurs only if you invoke the
|compiler with the pure ANSI flag (well, this is true of both of the lines
|of C++ compilers that I have any experience with). 

The ANSI-C standard makes it clear that the presence or lack of a 
"pure ANSI" flag in any otherwise conforming C compiler has nothing to
do with the ANSI-C language, but rather is an implementation detail.
As such these flags or lack thereof have nothing to do with this argument.

|>Again, I suggest that unless you have a very serious reason for requiring
|>changes to existing standard C libraries, leave well enough alone.
|
|They do.

Then they should state their reasons.  To date all that has been stated
for this blanket change to the base document is to return the name
space of the standard-C functions to the programmer.  Yet read the
ANSI-C standard and it becomes very clear that only a tiny handful of
these functions make sense as function-names to put in the C++ programmer's
name space.  If you want to intelligently and selectively decide to return
these handful of functions to the C++ programmer's name space, then I
support your efforts.  It's just that no good argument has been made
for returning the vast majority [the "decorated" names] to the C++
programmer.  The C++ programmer would be ill-advised to use such decorated
names, because C++ already has its own *automatic* name mangling scheme.
The C++ programmer can say:

	file.put('\n');

There is no good reason for the C++ programmer to say:

	file.fputc('\n');

since both the 'f' and the 'c' in "fputc" represent redundant manual
name mangling -- the programmer would be manually duplicating the efforts
that the compiler already supplies.  Such would simply be encouraging
bad C++ practice at the expense of prohibiting good C practice.  Which
is a lose-lose situation.