digito_evo
digito_evo

Reputation: 3682

Can namespace functions be declared at block scope?

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?

Upvotes: 0

Views: 163

Answers (1)

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.

Upvotes: 2

Related Questions