From: Daniel Krügler on
On 29 Apr., 21:01, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote:
> Daniel Kr�gler wrote:
> > static void afriend();
>
> > struct Sample {
> > private:
> > int m;
> > friend void afriend();
> > } s;
>
> > static void afriend() {
> > s.m = 12;
> > }
>
> Just wondering, is this an ODR violation when included more than once? The
> point is that different translation units have different afriend()s and
> class Sample thus picks a different afriend() every time.

It would not violate the ODR, because the two functions
named afriend with internal linkage within the
different translation units are different entities,
see [basic.link]/9:

"Two names that are the same (clause 3) and that are
declared in different scopes shall denote the same
object, reference, function, type, enumerator, template
or namespace if
� both names have external linkage or else both names have
internal linkage and are declared in the same translation
unit;[..]"

This means, that [basic.def.odr]/3 does not consider
the two function definitions to conflict with each other.

I agree that the wording in regard to names, entities and
linkage could be improved, see e.g. a previous posting of
Nikolay Ivchenkov (The meaning of "linkage").

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 30 Apr., 13:03, Daniel Kr�gler <daniel.krueg...(a)googlemail.com>
wrote:
> On 29 Apr., 21:01, Ulrich Eckhardt <eckha...(a)satorlaser.com> wrote:
>
>
>
> > Daniel Kr�gler wrote:
> > > static void afriend();
>
> > > struct Sample {
> > > private:
> > > int m;
> > > friend void afriend();
> > > } s;
>
> > > static void afriend() {
> > > s.m = 12;
> > > }
>
> > Just wondering, is this an ODR violation when included more than once? The
> > point is that different translation units have different afriend()s and
> > class Sample thus picks a different afriend() every time.
>
> It would not violate the ODR, because the two functions
> named afriend with internal linkage within the
> different translation units are different entities,
> see [basic.link]/9:
>
> "Two names that are the same (clause 3) and that are
> declared in different scopes shall denote the same
> object, reference, function, type, enumerator, template
> or namespace if
> � both names have external linkage or else both names have
> internal linkage and are declared in the same translation
> unit;[..]"
>
> This means, that [basic.def.odr]/3 does not consider
> the two function definitions to conflict with each other.

There is a different way to look at the same problem:
The ODR rules still apply for entities of internal linkage
such that any *missing* definition of a used entity
brings us in the UB domain. E.g. assume you have
prepared the following design:

// Header common.h:

static void foo(); // Only declared

// use.cpp:
#include <common.h>

static void foo() {};

void use() { foo(); }

// main.cpp:
#include <common.h>

extern void use();

int main() {
foo(); // #
use();
}

The line marked with a # comment is considered
as a use of main::foo() (in a symbolic sense), but
without the definition provided within the translation
unit named main here, this causes undefined
behavior.

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! ]