Re: Anonymous namespace and internal linkage

Discussion in 'C++' started by James Kanze, Feb 6, 2009.

  1. James Kanze

    James Kanze Guest

    On Feb 6, 9:33 am, Anand Hariharan <>
    wrote:
    > This code fails during linking:


    > namespace {
    > void FuncA()
    > {
    > /*extern*/ void FuncB(void);
    > FuncB();


    > }
    > void FuncB() {}
    > }


    > int main()
    > {
    > FuncA();
    > }


    > Is it to be expected?


    > Isn't 'extern' qualifier meaningless here?


    It should be.

    > It turns out that the linker does not have a problem when the
    > 'extern' is uncommented.


    That sounds like an error.

    Technically, of course, you have undefined behavior (both ways).
    But the FuncB called in FuncA is a function in the anonymous
    namespace; the FuncB you define isn't, so it isn't the same
    function.

    (FWIW: both Sun CC and g++ give a link error in both cases, with
    or without the extern. So does the version of VC++ that I have
    here: the one from Visual Studios 8.)

    > FWIW, here is the diagnostic, copy-pasted:


    > --- BEGIN ---
    > C:\temp>cl foo.cpp
    > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01
    > for 80x86
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > foo.cpp
    > Microsoft (R) Incremental Linker Version 9.00.30729.01
    > Copyright (C) Microsoft Corporation. All rights reserved.
    >
    > /out:foo.exe
    > foo.obj
    > foo.obj : error LNK2019: unresolved external symbol "void __cdecl FuncB
    > (void)" (
    > ?FuncB@@YAXXZ) referenced in function "void __cdecl `anonymous
    > namespace'::FuncA
    > (void)" (?FuncA@?A0xd21949b8@@YAXXZ)
    > foo.exe : fatal error LNK1120: 1 unresolved externals
    > --- END ---


    That's interesting. When I try this with VC++, I get:

    952@~/tmp/news (21): cl -Dextern= $VCPPFLAGS anon.cc
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version
    14.00.50727.762 for 80x86
    ...
    anon.obj : error LNK2019: unresolved external symbol "void __cdecl
    `anonymous na
    mespace'::funcB(void)" (?funcB@?A0xb676e5d1@@YAXXZ) referenced in
    function "void
    __cdecl `anonymous namespace'::funcA(void)" (?funcA@?
    A0xb676e5d1@@YAXXZ)

    (I've just cited the relevant lines: the version and the error
    message.) And this whether or not the "extern" is present.
    Note the difference in the error message, however---it clearly
    says that the missing function is in the anonymous namespace.
    The error messages of g++ and Sun CC are equally clear in this
    respect (for g++, at least under Linux---under Solaris, the Sun
    linker is used, and it doesn't know how to demangle the g++
    names, so the anonymous bit must be deduced by recognizing the
    mangling pattern).

    Since the version of the compiler you're using seems more
    recent than mine, I'd say that there is a regression error if
    it accepts the code, either with or without the "extern"; you
    should probably report it.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
    James Kanze, Feb 6, 2009
    #1
    1. Advertising

  2. On Feb 6, 7:40 am, James Kanze <> wrote:
    > On Feb 6, 9:33 am, Anand Hariharan <>
    > wrote:
    >
    > > This code fails during linking:
    > > namespace {
    > > void FuncA()
    > > {
    > > /*extern*/ void FuncB(void);
    > > FuncB();
    > > }
    > > void FuncB() {}
    > > }
    > > int main()
    > > {
    > > FuncA();
    > > }
    > > Is it to be expected?
    > > Isn't 'extern' qualifier meaningless here?

    >
    > It should be.
    >
    > > It turns out that the linker does not have a problem when the
    > > 'extern' is uncommented.

    >
    > That sounds like an error.
    >
    > Technically, of course, you have undefined behavior (both ways).
    > But the FuncB called in FuncA is a function in the anonymous
    > namespace; the FuncB you define isn't, so it isn't the same
    > function.
    >


    FuncB *is* defined in the anonymous namespace.

    Could you kindly clarify why it is UB?


    > (FWIW: both Sun CC and g++ give a link error in both cases, with
    > or without the extern. So does the version of VC++ that I have
    > here: the one from Visual Studios 8.)
    >
    >


    So how does one call a function defined farther down in the same file,
    in an anonymous namespace?


    > Since the version of the compiler you're using seems more
    > recent than mine, I'd say that there is a regression error if
    > it accepts the code, either with or without the "extern"; you
    > should probably report it.
    >


    Thanks to James, Sai and Daniel for the feedback.

    sincerely,
    - Anand


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
    Anand Hariharan, Feb 7, 2009
    #2
    1. Advertising

  3. James Kanze

    James Kanze Guest

    On Feb 7, 6:46 pm, Anand Hariharan <>
    wrote:
    > On Feb 6, 7:40 am, James Kanze <> wrote:


    > > On Feb 6, 9:33 am, Anand Hariharan <>
    > > wrote:


    > > > This code fails during linking:
    > > > namespace {
    > > > void FuncA()
    > > > {
    > > > /*extern*/ void FuncB(void);
    > > > FuncB();
    > > > }
    > > > void FuncB() {}
    > > > }
    > > > int main()
    > > > {
    > > > FuncA();
    > > > }
    > > > Is it to be expected?
    > > > Isn't 'extern' qualifier meaningless here?


    > > It should be.


    > > > It turns out that the linker does not have a problem when the 'extern'

    is
    > > > uncommented.


    > > That sounds like an error.


    > > Technically, of course, you have undefined behavior (both
    > > ways). But the FuncB called in FuncA is a function in the
    > > anonymous namespace; the FuncB you define isn't, so it isn't
    > > the same function.


    > FuncB *is* defined in the anonymous namespace.


    So I see. I misread your code, then made the mistake of
    reentering it, instead of copy/pasting it.

    > Could you kindly clarify why it is UB?


    If the definition of FuncB is outside of the unnamed namespace,
    you haven't provided a definition for the FuncB in the unnamed
    namespace. For the actual code, there is no UB---it's a fully
    conformant and correct program.

    > > (FWIW: both Sun CC and g++ give a link error in both cases,
    > > with or without the extern. So does the version of VC++ that
    > > I have here: the one from Visual Studios 8.)


    > So how does one call a function defined farther down in the
    > same file, in an anonymous namespace?


    As you did. With or without the extern---as you correctly
    assumed, the extern makes no difference here.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    --
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.moderated. First time posters: Do this! ]
    James Kanze, Feb 8, 2009
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Taras_96

    anonymous namespace and linkage

    Taras_96, Sep 6, 2008, in forum: C++
    Replies:
    10
    Views:
    593
    Taras_96
    Sep 26, 2008
  2. Replies:
    1
    Views:
    581
    Michael DOUBEZ
    Sep 12, 2008
  3. Bo Persson
    Replies:
    3
    Views:
    1,039
    James Kanze
    Feb 10, 2009
  4. puzzlecracker
    Replies:
    4
    Views:
    308
    Ron AF Greve
    Feb 7, 2009
  5. Stefan Ram
    Replies:
    0
    Views:
    61
    Stefan Ram
    Apr 18, 2014
Loading...

Share This Page