[LLVMbugs] [Bug 13252] New: Friend function definition and forward declaration

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Mon Jul 2 03:20:22 PDT 2012


http://llvm.org/bugs/show_bug.cgi?id=13252

             Bug #: 13252
           Summary: Friend function definition and forward declaration
           Product: clang
           Version: 3.1
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
        AssignedTo: unassignedclangbugs at nondot.org
        ReportedBy: romain.gerard at erebe.eu
                CC: dgregor at apple.com, llvmbugs at cs.uiuc.edu
    Classification: Unclassified


Hi,

I run into a case where clang is unable to associate a function declaration
with his definition. This was found while trying to port a "g++" code base with
clang.

Please consider this example,
#include <iostream>

class A;
void f(const A& a);

class A {

    public:
        explicit A():i(5) {}

        friend void f( const A& a) //Consider the friend
        {  std::cout << a.i << std::endl; } 

    private:
        int i;

};

int main(int argc, char **argv) {

    A a;
    f(a);
}

When compiling with "clang++ test.cpp" I get a linking error
--> test.cpp:(.text+0x20): undefined reference to `f(A const&)'

With "nm -C test.o"
0000000000000040 t global constructors keyed to a
                 U f(A const&) <----- Declared but doesn't have a definition
------------------------------------------------------------------------------
0000000000000000 W A::A()
0000000000000000 W A::A()
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
0000000000000000 b std::__ioinit
                 U __cxa_atexit
0000000000000000 t __cxx_global_var_init
                 U __dso_handle
0000000000000000 T main

In addition you can note that std::ostream::operator<<(int)is not listed, which
mean clang does know nothing of the definition of f(). 



So I played around and If you add the scope resolution operator when you call
f()in main, the association between declaration and definition is done.

int main(int argc, char **argv) {

    A a;
    ::f(a); //Note the operator
}

and I get with 'nm -C test.o'
0000000000000040 t global constructors keyed to a
0000000000000000 W f(A const&)   <--- Definition is found
----------------------------------------------------------------------
0000000000000000 W A::A()
0000000000000000 W A::A()
                 U std::ostream::operator<<(int) <-- This one is added
                 U std::ios_base::Init::Init()
                 U std::ios_base::Init::~Init()
                 U std::cout
0000000000000000 b std::__ioinit
                 U __cxa_atexit
0000000000000000 t __cxx_global_var_init
                 U __dso_handle
0000000000000000 T main


As same effect you can remove the forward declaration at the top of the file
and everything will work properly. 

//Remove this two lines and you are done
class A;
void f(const A& a);


My guess is it's due to definition of the friend function inside the class,
which should have some special cases. If you could enligthen me on this, I will
appreciate.  


Thanks

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list