Title
Redeclaration of extern "C" names via using-declarations
Status
tc1
Section
10.3.3 [namespace.udecl]
Submitter
Mike Miller

Created on 1999-03-10.00:00:00 last changed 208 months ago

Messages

Date: 1999-04-15.00:00:00

Proposed Resolution (10/99): As suggested.

Date: 2004-09-10.00:00:00

Consider the following:

    extern "C" void f();
    namespace N {
        extern "C" void f();
    }
    using N::f;
According to 10.3.3 [namespace.udecl] paragraph 11, the using-declaration is an error:
If a function declaration in namespace scope or block scope has the same name and the same parameter types as a function introduced by a using-declaration, the program is ill-formed.
Based on the context (10.3.3 [namespace.udecl] paragraph 10 simply reiterates the requirements of 6.3 [basic.scope] ), one might wonder if the failure to exempt extern "C" functions was intentional or an oversight. After all, there is only one function f() involved, because it's extern "C", so ambiguity is not a reason to prohibit the using-declaration.

This also breaks the relatively strong parallel between extern "C" functions and typedefs established in our discussion of Core issue 14 in Santa Cruz. There the question was for using-directives:

    typedef unsigned int size_t;
    extern "C" int f();
    namespace N {
        typedef unsigned int size_t;
        extern "C" int f();
    }
    using namespace N;
    int i = f();        // ambiguous "f"?
    size_t x;           // ambiguous "size_t"?
We decided for both that there was no ambiguity because each pair of declarations declares the same entity. (According to 6 [basic] paragraph 3, a typedef name is not an entity, but a type is; thus the declarations of size_t declare the same entity "unsigned int".)

In the context of using-declarations, there is no explicit extension of the restrictions in 6.3 [basic.scope] paragraph 4 except as noted above for function declarations; thus the parallel scenario for a typedef is not ill-formed:

    typedef unsigned int size_t;
    namespace N {
        typedef unsigned int size_t;
    };
    using N::size_t;        // okay, both declarations
                            // refer to the same entity
I think the first sentence of 10.3.3 [namespace.udecl] paragraph 11 ought to be rewritten as:
If a function declaration in namespace scope or block scope has the same name and the same parameter types as a function introduced by a using-declaration, and the declarations do not declare the same function, the program is ill-formed.
History
Date User Action Args
2003-04-25 00:00:00adminsetstatus: dr -> tc1
2000-02-23 00:00:00adminsetstatus: ready -> dr
1999-09-14 00:00:00adminsetmessages: + msg78
1999-03-10 00:00:00admincreate