Search code examples
c++argument-dependent-lookupfriend-function

namespace in debug flags of in-class defined friend functions


I'm dealing with a class that defines a friend function in the class without outside declaration

namespace our_namespace {
template <typename T>
struct our_container {

  friend our_container set_union(our_container const &, our_container const &) {
    // meaningless for the example here, just a valid definition
    // no valid semantics
    return our_container{};
  }
};
}  // namespace our_namespace

As discussed (e.g. here or here) the function set_union is not in the our_namespace namespace but will be found by argument dependent lookup:

auto foo(std::vector<our_namespace::our_container<float>> in) {
  // works:
  return set_union(in[0], in[1]);
}

I noticed however that in the debug flags set_union appears to be in the our_namespace namespace

        mov     rdi, qword ptr [rbp - 40] # 8-byte Reload
        mov     rsi, rax
        call    our_namespace::set_union(our_namespace::our_container<float> const&, our_namespace::our_container<float> const&)
        add     rsp, 48
        pop     rbp
        ret
our_namespace::set_union(our_namespace::our_container<float> const&, our_namespace::our_container<float> const&): # @our_namespace::set_union(our_namespace::our_container<float> const&, our_namespace::our_container<float> const&)
        push    rbp
        mov     rbp, rsp
        mov     qword ptr [rbp - 16], rdi
        mov     qword ptr [rbp - 24], rsi
        pop     rbp
        ret

although I can't call it as our_namespace::set_union

auto foo(std::vector<our_namespace::our_container<float>> in) {
  // fails:
  return our_namespace::set_union(in[0], in[1]);
}

Any hints about how the debug information is to be understood?

EDIT: The set_union function body is only a strawdog example here to have a valid definition.


Solution

  • The C++ standard only defines compiler behavior in regards to the code compilation and behavior of the resulting program. It doesn't define all the aspects of code generation, and in particular, it doesn't define debug symbols.

    So your compiler correctly (as per Standard) disallows calling the function through namespace it is not in. But since the function does exist and you should be able to debug it, it needs to put debug symbol somewhere. Enclosing namespace seems to be a reasonable choice.