Is this legal?

M

Mark P

I was helping a coworker port some code to a new compiler (HP). He had
something along the lines of this:

class C { // defined in the global namespace
static int foo();
};

namespace {
int C::foo() {...}
};

The compiler complained: A definition of a namespace declaration
must be written in directly in the namespace (unqualified) or in an
enclosing namespace (qualified).

The fix of course is obvious, and I'm not sure what his motivation was
to put only the definition in the unnamed namespace, but two other
compilers (Linux gcc and Sun) had not complained about this.

So I wonder, is his code standard compliant or not? (And if so, is
there any reason why one would want to do this?)

Thanks,
Mark
 
A

Andre Kostur

I was helping a coworker port some code to a new compiler (HP). He had
something along the lines of this:

class C { // defined in the global namespace
static int foo();
};

namespace {
int C::foo() {...}
};

The compiler complained: A definition of a namespace declaration
must be written in directly in the namespace (unqualified) or in an
enclosing namespace (qualified).

I can't point at the Standard and say where it's wrong, but intuitively it
seems wrong. There is no class C within the anonymous namespace (think of
an anonymous namespace as one with a random name. You don't know what it
is, but the compiler and linker do). So basically that code seems to be
trying to do (effectively):

int _AnonNamespace1::C::foo() {...}
 
V

Victor Bazarov

Mark said:
I was helping a coworker port some code to a new compiler (HP). He
had something along the lines of this:

class C { // defined in the global namespace
static int foo();
};

namespace {
int C::foo() {...}
};

The compiler complained: A definition of a namespace declaration
must be written in directly in the namespace (unqualified) or in an
enclosing namespace (qualified).

The fix of course is obvious, and I'm not sure what his motivation was
to put only the definition in the unnamed namespace, but two other
compilers (Linux gcc and Sun) had not complained about this.

So I wonder, is his code standard compliant or not? (And if so, is
there any reason why one would want to do this?)

My first thought was, 'no, of course not'. Then I tried to reason with
myself hoping to find a possibility of it's being legal. I couldn't
find any. Then I tried Comeau, and the code was promptly rejected (even
after replacing '...' with 'return 42;' and removing of the stand-alone
semicolon after the namespace definitions. That only confirms that the
code is not legal (knowing that Comeau is one of the most compliant
compilers out there).

The only explanation I can think of is that somebody had heard that now
'static' should not be used for functions any more and instead anonymous
namespaces should be used (actually the use of 'static' declarator for
declaring non-member functions whose scope is limited to the file in which
they appear *was* deprecated). So, that somebody decided to place all the
definitions of static member functions in anonymous namespaces -- weird
yet explainable. Now, as to why it [allegedly] worked with gcc and Sun
compilers, I don't know. Were the functions actually used?

V
 
G

Greg

Mark said:
I was helping a coworker port some code to a new compiler (HP). He had
something along the lines of this:

class C { // defined in the global namespace
static int foo();
};

namespace {
int C::foo() {...}
};

The compiler complained: A definition of a namespace declaration
must be written in directly in the namespace (unqualified) or in an
enclosing namespace (qualified).

The fix of course is obvious, and I'm not sure what his motivation was
to put only the definition in the unnamed namespace, but two other
compilers (Linux gcc and Sun) had not complained about this.

So I wonder, is his code standard compliant or not? (And if so, is
there any reason why one would want to do this?)

Thanks,
Mark

C::foo cannot be placed in an unnamed namespace unless there is a class
C defined in that same, unnamed namespace. So the HP compiler is indeed
correct that C::foo cannot be placed in an unnamed namespace in this
case; but that fact does not necessarily mean that a compilation error
has occurred. In fact most C++ compilers (EDG, VC 7.1, CW 9.5, GNU
4.01) will simply not place C::foo in the unnamed namespace and carry
on as usual. And there is little in the Standard that would seem to
require a C++ compiler to do any more than just that.

The HP compiler does the right thing to complain about C::Foo's
declaration - because it does suggest some kind of likely error on the
user's part. But the HP compiler may be exaggerating a bit when it
reports the issue as a compilation error.

Greg
 
A

Alf P. Steinbach

* Victor Bazarov:
(actually the use of 'static' declarator for
declaring non-member functions whose scope is limited to the file in which
they appear *was* deprecated).

Was it?
 
A

Alf P. Steinbach

* Mark P:
I was helping a coworker port some code to a new compiler (HP). He had
something along the lines of this:

class C { // defined in the global namespace
static int foo();
};

namespace {
int C::foo() {...}
};

The compiler complained: A definition of a namespace declaration
must be written in directly in the namespace (unqualified) or in an
enclosing namespace (qualified).

The fix of course is obvious, and I'm not sure what his motivation was
to put only the definition in the unnamed namespace, but two other
compilers (Linux gcc and Sun) had not complained about this.

So I wonder, is his code standard compliant or not? (And if so, is
there any reason why one would want to do this?)

§9.3/2 "A member function function definition that appears outside of
the class definition shall appear in a namespace scope enclosing the
class definition."
 
R

roberts.noah

Alf said:
* Mark P:

§9.3/2 "A member function function definition that appears outside of
the class definition shall appear in a namespace scope enclosing the
class definition."

Would global scope do the trick?

int ::C::foo() {}
 
A

Alf P. Steinbach

* (e-mail address removed):
* Alf P. Steinbach:

Would global scope do the trick?

int ::C::foo() {}

If placed at global scope, yes, I would think so.

If placed within some namespace that does not enclose the class
definition, AAAARRGH!, I suspect not, but I don't really know.

Rule of thumb, though: don't skirt the edges of the language definition.
 
R

roberts.noah

Alf said:
* (e-mail address removed):

If placed at global scope, yes, I would think so.

If placed within some namespace that does not enclose the class
definition, AAAARRGH!, I suspect not, but I don't really know.

Rule of thumb, though: don't skirt the edges of the language definition.

Pretty grotty declaring and defining class members in different
namespaces anyway. I was just curious.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top