Home > Software design >  Can namespace functions be declared at block scope?
Can namespace functions be declared at block scope?

Time:02-01

Can namespace functions be declared at block scope outside the namespace they were defined at?

This code does not compile when DECLARED_IN_NS is defined as 1:

#define DECLARED_IN_NS 1 // can be either 0 or 1


#if DECLARED_IN_NS == 1
namespace ns
{
#endif

void
func1()
{
}

void
func2()
{
}

#if DECLARED_IN_NS == 1
} // namepace ns
#endif

int main( )
{
#if DECLARED_IN_NS == 1

    void ns::func1(); // compile error
    void ns::func2(); // compile error

    ns::func1();
    ns::func2();

#elif DECLARED_IN_NS == 0

    void func1();
    void func2();

    func1();
    func2();

#endif
}

It shows some errors:

error: qualified-id in declaration before '(' token
   28 |     void ns::func1();
      |                   ^

The code compiles when func1 and func2 are defined at global namespace. However, it doesn't compile when they are defined inside a namespace (e.g. ns).

Is there a way to fix this?

CodePudding user response:

I can't find a definitive reference to this in the standard, but I don't think there'd be much point to allow it intentionally.

Even if it could appear at block scope, it'd be pointless. A declaration that uses a nested name specifier cannot be the first declaration for an entity.

[dcl.meaning.general]

1 When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers (or, in the case of a namespace, of an element of the inline namespace set of that namespace ([namespace.def])) ...

This makes this code like this valid

namespace ns
{
void func();

} // namepace ns


void ns::func(); // repeated declaration - optional
void ns::func() { // definition
}

Now, returning to the block scope case, you'd need a namespace scoped declaration preceding it anyway, so the whole exercise is moot.

Furthermore, the behavior of declaring functions in block scope has aspects that are aptly named by the c community, but it remains due to C compatibility. It would certainly not be beneficial to allow it for nested names intentionally.

  • Related