Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning defining friend operator declared inside a namespace

Someone can explain me a warning from g++ ?

Given the following code

#include <iostream>

namespace foo
 {
   struct bar
    { friend std::ostream & operator<< (std::ostream &, bar const &); };
 }

std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
 { return o; }

int main ()
 {
   foo::bar  fb;

   std::cout << fb;
 }

I get (from g++ (6.3.0) but not from clang++ (3.8.1) and not (thanks Robert.M) from Visual Studio (2017 community)) this warning

tmp_002-11,14,gcc,clang.cpp:10:16: warning: ‘std::ostream& foo::operator<<(std::ostream&, const foo::bar&)’ has not been declared within foo
 std::ostream & foo::operator<< (std::ostream & o, foo::bar const &)
                ^~~
tmp_002-11,14,gcc,clang.cpp:7:29: note: only here as a friend
     { friend std::ostream & operator<< (std::ostream &, bar const &); };
                             ^~~~~~~~

I know that I can define the operator as follows

namespace foo
 {
   std::ostream & operator<< (std::ostream & o, bar const &)
    { return o; }
 }

but... what's wrong with my initial code ?

like image 763
max66 Avatar asked Jun 25 '17 19:06

max66


1 Answers

Consider this simple program:

namespace xxx { 
    struct foo {
       friend void bar();
    };
}

int main() {
    xxx::bar();
}

You will get a compilation error (with clang too) because bar is not declared in namespace xxx.

Now consider this:

namespace xxx {}
void xxx::bar() {}

This will also fail for the same exact reason, bar is not declared in namespace xxx.

Now when you combine the two, there's no reason why the combination should suddenly become legal. bar is still not declared in namespace xxx. Yet clang permits it. This behaviour is inconsistent and confusing, and is best described as a bug.

like image 70
n. 1.8e9-where's-my-share m. Avatar answered Oct 14 '22 12:10

n. 1.8e9-where's-my-share m.