From: Chris Vine on
I require a function which must have a C linkage specification (it is a
callback from a C library) to be a friend of a class in order to have
access to protected member functions of the class: it forms part of the
class implementation. Because it has to be a friend it must be
declared in the class header file providing the class definition.

To minimise intercoupling with other translation units which might look
up the header file, I thought of putting it in anonymous namespace,
thus:

// *** class definition ***

namespace {
extern "C" void my_callback(void* data);
}

class MyClass {
protected:
void do_it();
public:
friend void my_callback(void* data);
};

// *** class implementation ***

namespace {
void my_callback(void* data) {
// data here holds a pointer to a MyClass object
static_cast<MyClass*>(data)->do_it();
}
}

void MyClass::do_it() {}

// *** end of code

However, this fails to compile with gcc-4.4 and gcc-4.5 with:
namespace.cpp:9: error: 'void MyClass::do_it()' is protected
namespace.cpp:19: error: within this context

In order to enable the friend declaration really to make the function a
friend of the class, I need to wrap it in a named namespace, such as:

// *** class definition ***

namespace {
namespace CB {
extern "C" void my_callback(void* data);
}
}

class MyClass {
protected:
void do_it();
public:
friend void CB::my_callback(void* data);
};

// *** class implementation ***

namespace {
void CB::my_callback(void* data) {
// data here holds a pointer to a MyClass object
static_cast<MyClass*>(data)->do_it();
}
}

void MyClass::do_it() {}

// *** end of code

I thought every unnamed namespace declaration had with it an implicit
using directive. What is the reason why one friend declaration works
and not the other, and is there a better way of doing it, such as by
making the function static? As functions with C linkage do not name
mangle for namespaces (look-up when linking is not affected), is placing
it in anonymous namespace entirely otiose anyway?

Chris


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
Chris Vine wrote:
> I require a function which must have a C linkage specification (it is a
> callback from a C library) to be a friend of a class in order to have
> access to protected member functions of the class: it forms part of the
> class implementation. Because it has to be a friend it must be
> declared in the class header file providing the class definition.

Okay, so far.

> To minimise intercoupling with other translation units which might look
> up the header file, I thought of putting it in anonymous namespace,
> thus:
>
> // *** class definition ***
>
> namespace {
> extern "C" void my_callback(void* data);
> }

Putting this into a header file will declare this function over and over
again, each time in a different anonymous namespace when you include the
header file from other translation units. This is ugly, but not necessarily
a problem.

> class MyClass {
> protected:
> void do_it();
> public:
> friend void my_callback(void* data);
> };
>
> // *** class implementation ***
>
> namespace {
> void my_callback(void* data) {
> // data here holds a pointer to a MyClass object
> static_cast<MyClass*>(data)->do_it();
> }
> }

Actually, what this does is to declare a second, unrelated anonymous
namespace and inside a function with the same name (but different linkage!)
than the one declared in the first namespace.

> However, this fails to compile with gcc-4.4 and gcc-4.5 with:
> namespace.cpp:9: error: 'void MyClass::do_it()' is protected
> namespace.cpp:19: error: within this context

Different function, not a friend.

> In order to enable the friend declaration really to make the function a
> friend of the class, I need to wrap it in a named namespace, such as:
>
> // *** class definition ***
>
> namespace {
> namespace CB {
> extern "C" void my_callback(void* data);
> }
> }
>
> class MyClass {
> protected:
> void do_it();
> public:
> friend void CB::my_callback(void* data);
> };
>
> // *** class implementation ***
>
> namespace {
> void CB::my_callback(void* data) {
> // data here holds a pointer to a MyClass object
> static_cast<MyClass*>(data)->do_it();
> }
> }

I'm surprised this works and I'm not sure it is legal. What might be legal
is to just define it in the implementation file while skipping the (IMHO
illegal) attempt to fully qualify the name:

void CB::my_callback(void* data) { ... }

Maybe that is even what is actually used. Since the namespace "CB" doesn't
exist in the second anonymous namespace, it probably uses normal lookup
rules and looks in the surrounding namespaces where it finds the "CB" from
the first anonymous namespace, which was imported via the implicit using
directive.


> As functions with C linkage do not name mangle for namespaces
> (look-up when linking is not affected), is placing it in
> anonymous namespace entirely otiose anyway?

Name mangling is not the issue here, I guess the linker symbol is entirely
unused and only the function's address is.

What I would do is to put the function into its own name space. Two variants
come to mind:
1. Using a unique prefix:
extern "C" void MyClassCallbackHelper(void*);
This already separates it sufficiently from other code.
2. Using a C++ namespace:
namespace MyClassHelper { extern "C" void callback(); }
This becomes more useful than the above variant the more of those functions
you have.

Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Chris Vine on
On Tue, 20 Jul 2010 08:07:48 CST
Ulrich Eckhardt <eckhardt(a)satorlaser.com> wrote:
> Chris Vine wrote:
[snip]
> > To minimise intercoupling with other translation units which might
> > look up the header file, I thought of putting it in anonymous
> > namespace, thus:
> >
> > // *** class definition ***
> >
> > namespace {
> > extern "C" void my_callback(void* data);
> > }
>
> Putting this into a header file will declare this function over and
> over again, each time in a different anonymous namespace when you
> include the header file from other translation units. This is ugly,
> but not necessarily a problem.

That was really the intention: that is, to avoid global namespace
pollution by sharing the header file. (But on looking at it further I
don't now think it is achieved satisfactorily, as I say at the end.)

[snip]
> >// *** class implementation ***
> >
> > namespace {
> > void my_callback(void* data) {
> > // data here holds a pointer to a MyClass object
> > static_cast<MyClass*>(data)->do_it();
> > }
> > }
>
> Actually, what this does is to declare a second, unrelated anonymous
> namespace and inside a function with the same name (but different
> linkage!) than the one declared in the first namespace.

Are you sure? When the function definition is compiled it will always
have the function declaration in its own translation unit, so at that
point they will share the same unnamed namespace. Paragraph 7.3.1.1/1
of the draft C++0x standard says "all occurrences of unique in a
translation unit are replaced by _the same_ identifier, and this
identifier differs from all other identifiers in the entire
program" (my emphasis), and I think the current standard says the same.

[snip]
> > In order to enable the friend declaration really to make the
> > function a friend of the class, I need to wrap it in a named
> > namespace, such as:
> >
> > // *** class definition ***
> >
> > namespace {
> > namespace CB {
> > extern "C" void my_callback(void* data);
> > }
> > }
[snip]
> > // *** class implementation ***
> >
> > namespace {
> > void CB::my_callback(void* data) {
> > // data here holds a pointer to a MyClass object
> > static_cast<MyClass*>(data)->do_it();
> > }
> > }
>
> I'm surprised this works and I'm not sure it is legal. What might be
> legal is to just define it in the implementation file while skipping
> the (IMHO illegal) attempt to fully qualify the name:
>
> void CB::my_callback(void* data) { ... }
>
> Maybe that is even what is actually used. Since the namespace "CB"
> doesn't exist in the second anonymous namespace, it probably uses
> normal lookup rules and looks in the surrounding namespaces where it
> finds the "CB" from the first anonymous namespace, which was imported
> via the implicit using directive.

As I mention above, at the point CB::my_callback() is compiled the
function definition is in the same translation unit as its definition
and thus in the same unnamed namespace, so this looks legal to me.

> > As functions with C linkage do not name mangle for namespaces
> > (look-up when linking is not affected), is placing it in
> > anonymous namespace entirely otiose anyway?
>
> Name mangling is not the issue here, I guess the linker symbol is
> entirely unused and only the function's address is.
>
> What I would do is to put the function into its own name space. Two
> variants come to mind:
> 1. Using a unique prefix:
> extern "C" void MyClassCallbackHelper(void*);
> This already separates it sufficiently from other code.
> 2. Using a C++ namespace:
> namespace MyClassHelper { extern "C" void callback(); }
> This becomes more useful than the above variant the more of those
> functions you have.

On thinking about it further I think option 1 is much to be preferred,
because the prefix will also act as a name space against any other
functions of similar name in the same program also with C linkage
(which might be linked in via a library). Paragraph 7.5/6 of the draft
C++0x standard says:

"At most one function with a particular name can have C language
linkage. Two declarations for a function with C language linkage with
the same function name (ignoring the namespace names that qualify it)
that appear in different namespace scopes refer to the same function.
Two declarations for an object with C language linkage with the same
name (ignoring the namespace names that qualify it) that appear in
different namespace scopes refer to the same object. [Note: because of
the one definition rule (3.2), only one definition for a function or
object with C linkage may appear in the program; that is, such a
function or object must not be defined in more than one namespace
scope ..."

It means that notwithstanding the deprecation of the use of the static
keyword in favour of unnamed namespace, internal linkage via the static
keyword is the only means of isolating a function with C linkage and
preventing a name clash at link time with another function with C
linkage of the same name. Unnamed namespaces appear to be useless for
functions with C linkage.

In this regard, the one definition rule as formulated in the draft
C++0x standard appears to break C compatibility (including for C++
programs linking to C libraries). It states that "Every program shall
contain exactly one definition of every non-inline function or variable
that is used in that program; no diagnostic required." It appears to
make no exception for functions with internal linkage (as opposed to
inline functions, for which it does make an exception), but presumably
no sane compiler is actually going to create a name conflict between
two functions wth internal linkage defined in different translation
units where one or more of them are linked in from a C library.

Chris

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 20 Jul., 16:07, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote:
> Chris Vine wrote:

[..]

> > In order to enable the friend declaration really to make the function a
> > friend of the class, I need to wrap it in a named namespace, such as:
>
> > // *** class definition ***
>
> > namespace {
> > namespace CB {
> > extern "C" void my_callback(void* data);
> > }
> > }
>
> > class MyClass {
> > protected:
> > void do_it();
> > public:
> > friend void CB::my_callback(void* data);
> > };
>
> > // *** class implementation ***
>
> > namespace {
> > void CB::my_callback(void* data) {
> > // data here holds a pointer to a MyClass object
> > static_cast<MyClass*>(data)->do_it();
> > }
> > }
>
> I'm surprised this works and I'm not sure it is legal. What might be legal
> is to just define it in the implementation file while skipping the (IMHO
> illegal) attempt to fully qualify the name:
>
> void CB::my_callback(void* data) { ... }
>
> Maybe that is even what is actually used. Since the namespace "CB" doesn't
> exist in the second anonymous namespace, it probably uses normal lookup
> rules and looks in the surrounding namespaces where it finds the "CB" from
> the first anonymous namespace, which was imported via the implicit using
> directive.

Whether it works depends how the OP actually provided
the implementation. As you descibed in a previous part
(not repeated here), there can be problems, if the
header is included in more than one translation unit.
You are right, that a *qualified* friend-declaration
will follow normal lookup-rules. This is (somewhat
indirectly) described in [namespace.memdef]/3,
especially with the recently added note in the
FCD:

"[ Note: the other forms of friend declarations
cannot declare a new member of the innermost
enclosing namespace and thus follow the usual
lookup rules. �end note ]"

As you describe, it is possible to define the
function just as

void CB::my_callback(void* data) { ... }

because namespace CB can be referenced by name
within the global namespace (see also
[namespace.qual]/6 in C++03 or [namespace.qual]/7
in the FCD)

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 20 Jul., 21:10, Chris Vine <ch...(a)cvine--nospam--.freeserve.co.uk>
wrote:
> On Tue, 20 Jul 2010 08:07:48 CST

> > >// *** class implementation ***
>
> > > namespace {
> > > void my_callback(void* data) {
> > > // data here holds a pointer to a MyClass object
> > > static_cast<MyClass*>(data)->do_it();
> > > }
> > > }
>
> > Actually, what this does is to declare a second, unrelated anonymous
> > namespace and inside a function with the same name (but different
> > linkage!) than the one declared in the first namespace.
>
> Are you sure? When the function definition is compiled it will always
> have the function declaration in its own translation unit, so at that
> point they will share the same unnamed namespace. Paragraph 7.3.1.1/1
> of the draft C++0x standard says "all occurrences of unique in a
> translation unit are replaced by _the same_ identifier, and this
> identifier differs from all other identifiers in the entire
> program" (my emphasis), and I think the current standard says the same.

Its still unclear to me how you provide your *single*
implementation of the extern "C" function with name
my_callback. Since it is an function with external
linkage there can only be one definition. Since it
is an extern "C" function, all these functions "named"
by different unnamed namespaces are referring to
the same function. So you can only provide a *single*
definition in one translation unit without violating
the ODR.

> > void CB::my_callback(void* data) { ... }
>
> > Maybe that is even what is actually used. Since the namespace "CB"
> > doesn't exist in the second anonymous namespace, it probably uses
> > normal lookup rules and looks in the surrounding namespaces where it
> > finds the "CB" from the first anonymous namespace, which was imported
> > via the implicit using directive.
>
> As I mention above, at the point CB::my_callback() is compiled the
> function definition is in the same translation unit as its definition
> and thus in the same unnamed namespace, so this looks legal to me.

It would violate the ODR, if at least a second translation
unit also provides a definition of my_callback. It is
completely irrelevant, how different the namespace names
are - the namespace protection works only on the
C++ level. Consider:

namespace A {
extern "C" void foo() {}
}

namespace B {
extern "C" void foo() {}
}

This is already ill-formed, because there are two
definitions of foo() in the same translation unit.

If these exist in two different translation units,
you would violate the ODR in a way that causes
undefined behavior, unless both separate definitions
where declared as inline functions.

> Unnamed namespaces appear to be useless for functions with C linkage.

This is correct.

> In this regard, the one definition rule as formulated in the draft
> C++0x standard appears to break C compatibility (including for C++
> programs linking to C libraries). It states that "Every program shall
> contain exactly one definition of every non-inline function or variable
> that is used in that program; no diagnostic required." It appears to
> make no exception for functions with internal linkage (as opposed to
> inline functions, for which it does make an exception), but presumably
> no sane compiler is actually going to create a name conflict between
> two functions wth internal linkage defined in different translation
> units where one or more of them are linked in from a C library.

This is no break versus C. If you have multiple definitions
of a function named X with internal linkage in different
translation units, all these functions are independent and
different entities, so they are not the same function and
the fact that all of them provide a single definition is
*not* a violation of the ODR.

The extra-case mentioned for inline functions is necessary,
because the wording gives freedom to provide *multiple*
definitions of the *same* function - this is completely
unique.

The behaviour of compilers in regard to function definitions
with internal linkage has nothing to do with saneness, it
is required. There are *no* duplicate definitions! In contrast:
If you would omit a single definition of such a function
that is used in the program, you are violating the ODR.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]