Topic: How are extern "C" and namespace supposed to interact


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/09/21
Raw View
Linkage wrote:
>
> Is the interaction of these clauses defined?  I ask because on the new Sun
> C++ 6.0
> the affect of including <cstdio> is something like:
>
> extern "C" {
>     namespace std {
>         char * sprintf(char *, ...);
>     }
> }
>
> To compile the compiler requires
>
>     std::sprintf
>
> yet produces an object link symbol against the global (non-namespace)
> function
>
>     sprintf
>
> Is this correct behaviour?

Yes. All extern "C" functions of the same name are the same,
but you can only use them in scopes where they have been defined.

Example:

namespace foo
{
  extern "C" int f() { return 0; }
}

namespace bar {}

int i1 = foo::f();    // OK
int i2 = f();         // error: no global f
int i3 = bar::f();    // error: no f in bar

namespace bar
{
  extern "C" int f(); // re-declaration of the C-function f
                      // previously defined in namespace foo
                      // but now in namespace bar
}

int i4 = f();         // still an error
int i5 = bar::f();    // OK, calls bar::f, same as foo::f

extern "C" int f();

int i6 = foo::f();    // OK, calls ::f(), same as foo::f()

namespace baz
{
  int f();            // C++ function, different from foo::f
}

int i7 = baz::f();    // unless baz::f() gets defined somewhere,
                      // this is a link error. In no case this is
                      // linked to foo::f.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Linkage" <neil.mowbray@tokaiasia.com.hk>
Date: 2000/09/15
Raw View
Is the interaction of these clauses defined?  I ask because on the new Sun
C++ 6.0
the affect of including <cstdio> is something like:

extern "C" {
    namespace std {
        char * sprintf(char *, ...);
    }
}

To compile the compiler requires

    std::sprintf

yet produces an object link symbol against the global (non-namespace)
function

    sprintf

Is this correct behaviour?

More generally, are the "standard C" functions like sprintf, fprint etc
supposed
to be in std or not.  If they are in, how can there be any compatibility
between
the "C subset" of C++ and ISO C.

Regards,
Neil Mowbray



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Steve Clamage <stephen.clamage@sun.com>
Date: Sat, 16 Sep 2000 06:13:18 GMT
Raw View
Linkage wrote:
>
> Is the interaction of these clauses defined?

Yes. Section 7.5 paragraph 6. Namespace qualifications do not affect
the external "real" names of functions declared extern "C".

namespace N { extern "C" int f(int); }
namespace M { extern "C" int f(int); }
extern "C" int f(int k) { return k; }

The above declarations and definition are all the same function.
You can refer to the function in C++ source code as f, M::f, or
N::f. Since the purpose of declaring C linkage is to allow a C
function to be called from C++ and vice versa, we would expect
the external "real" name of f to be the same one the C compiler
would use.

If the declarations all had C++ linkage, each would refer to
a different function, and their external "real" names would
have to be different, or would have to be qualified in some
way so as to tell them apart reliably at run time.

>
> More generally, are the "standard C" functions like sprintf, fprint etc
> supposed
> to be in std or not.  If they are in, how can there be any compatibility
> between
> the "C subset" of C++ and ISO C.

If you include the <cHDR> version of a standard C header, the names from
that header are supposed to be visible only in namespace std. If you
include the <HDR.h> version of the header, the names are supposed to be
visible in both namespace std and in the global namespace.  Not all
compilers, notably VC++, follow those rules.

The following two programs are both valid in standard C++:

#include <cstdio>                         #include <stdio.h>
int main()                                int main()
{                                         {
    std::printf("Hello\n");                    printf("Hello\n");
}                                         }

The usual implementation is to pick up the C functions from the C
library, and declare them with C linkage in the headers. (Some
functions are required to have overloaded versions, meaning that
at most one of each set can have C linkage.)  But it is unspecified
whether any of the functions inherited from C have C or C++ linkage.
In principle, some could have different linkages, such as Fortran.

Unlike C, you are not allowed in C++ to provide your own declarations
for the C library functions, because you don't know in advance how
they will be defined by the implementation.

--
Steve Clamage, stephen.clamage@sun.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]