This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 113d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-03-20


101. Redeclaration of extern "C" names via using-declarations

Section: 9.9  [namespace.udecl]     Status: TC1     Submitter: Mike Miller     Date: 10 Mar 1999

Consider the following:

    extern "C" void f();
    namespace N {
        extern "C" void f();
    }
    using N::f;
According to 9.9 [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 (9.9 [namespace.udecl] paragraph 10 simply reiterates the requirements of 6.4 [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.1 [basic.pre] 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.4 [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 9.9 [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.

Proposed Resolution (10/99): As suggested.