This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Prevent macro expansion of mblen


Alexandre Oliva <aoliva@redhat.com> writes:

| On Dec 28, 2000, Gabriel Dos Reis <gdr@codesourcery.com> wrote:
| 
| > We want all C-functions, whether there are shadowed (i.e. brought in
| > scope through <cxxx> or <xxx.h> headers) have C linkage  -- this
| > ensures that those names ultimately refer to the same entities --
| 
| Will you please explain again what your plan is to accomplish this in
| case the C library offers a standard function as both a preprocessor
| macro and a function with C linkage in the global namespace, and in
| case it is only offered as a preprocessor macro?

Well, 

 * In the first case, we need to #undef the macro and introduce a
   declaration in namespace std;

 * In the second case, we also #undef the macro and introduce a
   declaration.  But here, we need to be careful and introduce a
   function name with an external "C" linkage -- see below.

| I see your solution is ok for the latter, but not for the former,
| which is the case on IRIX 5.  If mblen were defined as an inline
| extern "C" function, there would be two different implementations of
| the same function, both of them with C linkage, which (I think)
| violates the ODR.

You are right.

| Maybe we should just #undef the macro, in this case, which would also
| get us rid of the optimization provided by the preprocessor macro?

If the target provides *both* forms then it is OK to #undef the macro
and introduce a function declaration with "C" linkage in namespace std.

| What I don't understand is why it is so important that the inline
| function in the std namespace be extern "C". 

To introduce a plateform independent behaviour -- this is actually
more than a quality of implementation issue.  Consider the following
example.

Consider a target which provides only the macro version (I'm not sure
that is valid, but let's make that assumption for the sake of
exposition).  If we didn't mark the corresponding function with a C
linkage then the following will be OK

	#include <xxx>	// this happens to include <cstdlib>
			// but user Jack doesn't know

	// This is silly but happens from time to time

	namespace MyNamespace {
		// Jack's "improved" version of mblen
		inline int mblen(const char* p, size_t l) // WRONG
		{ /* ... */ }
	}

Jack will use MyNamespace::mblen() in his code and that will "works"
on his target until his code is moved to a target which provides both
forms of mblen().  Then user Jack will send us a bug report saying his
code used to work on target foo.  We could then reply "that was not
guaranteed to work, as it is unspecified whether mblen() has C linkgage
or not".  That abstract answer will be abstractly right but will be of
no much practical help for user Jack.  Since we have the ability to
catch that error earlier, I don't see why we should not do it in
the first place.  
And, removing that "unspecified status" from our implementation
introduces  one more deterministic bit into the library behaviour.  I
don't see any compeling reason not to do it.

Am I still mistunderstanding your situation?

-- Gaby
CodeSourcery, LLC                       http://www.codesourcery.com

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]