Topic: unnamed namespace names used in template bug? (MW Code Warrior)
Author: AllanW@my-dejanews.com
Date: 1998/12/21 Raw View
In article <slrn77qrbb.i0h.sbnaran@localhost.localdomain>,
sbnaran@uiuc.edu wrote:
>
> On 20 Dec 1998 18:12:21 GMT, Gargantua Blargg <blargg@flash.net> wrote:
>
> [Discussing why entities in unnamed namespaces are superior to
> entities declared static].
>
> Note that only objects and non-member functions can be static.
> But you can put anything in unnamed namespaces -- class
> definitions, member functions, non-member functions, objects.
> So unnamed namespaces are better from a theoretical point of
> view: they allow you to give anything the effect of internal
> linkage, whereas 'static' allows you to give only non-member
> functions and objects the effect of internal linkage.
>
> >The reason being, of course, to lighten the load on the linker, since most
> >objects in an unnamed namespace won't ever be used by the linker outside
> >the file, except those used by templates where the template isn't
> >generated during compilation of the file.
>
> Good reason.
You quoted that paragraph out of context. In article
<75gmv3$pnt$1@engnews2.Eng.Sun.COM>, stephen.clamage@sun.com
(Steve Clamage) wrote:
> Most current compilers take the shortcut of giving things in
> unnamed namespaces internal linkage, as if they were "static".
> This shortcut removes the need to generate unique names, but
> doesn't allow use of entities in unnamed namespaces as template
> actual parameters.
And then Gargantua Blargg wrote that paragraph in response. You
made it look as if he was talking about the reason for "static,"
but in fact he was actully talking about the practice of some
compilers to ACT AS IF certain declarations had been declared
static.
> One reason why functions in unnamed namespaces are superior to static
> functions is to make long distance friendship a little safer.
[Goes on to explain the "long distance freindship" fraud.]
> In short, the old reason that long distance friendship violates
> encapsulation because someone can steal the friendship is no
> longer valid. But the other reason against long distance
> friendship remains: it leads to designs that are harder to
> comprehend, harder to keep straight in our minds.
This argument has been made before, but I still don't buy it. It's
already illegal C++ (because of the One Definition Rule). The fact
that many compilers won't catch it doesn't make it valid.
Furthermore, the examples you cite clearly broke the rules
intentionally. They went out of their way to do so. This is called
"fraud." C++ has been designed to prevent accident, not fraud.
Common mistakes are within the scope of the C++ language, but fraud
is not. In fact, any computer language which is both powerful and
low-level CANNOT reasonably be defined to prevent fraud, at least
not while there are some programmers with access to text editors.
Because even if we could reasonably make this particular form of
fraud impossible (and I'm not convinced it's possible, without
removing plenty of very useful language features), there are still
plenty of other fraudulent "techniques" available.
> However, good design says that a friend function declared in
> SOMEFILE.H should be defined in the file SOMEFILE.C. Provided
> we only use this kind of long distance friendship, we should
> be ok. (See Lakos for details).
Are you suggesting that compilers require this? Even this wouldn't
stop fraud, because it's easy to create local versions of SOMEFILE.C
and modify them.
Or are you just suggesting that programmers shouldn't commit fraud?
I would take this as incontroversial.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: blargg@flash.net (Gargantua Blargg)
Date: 1998/12/19 Raw View
In article
<MWRon-1812981730570001@dyn1-tnt1-244.kalamazoo.mi.ameritech.net>,
MWRon@metrowerks.com (MW Ron) wrote:
> In article <blargg-1712981238210001@p119.amax18.dialup.aus1.flash.net>,
> blargg@flash.net (Gargantua Blargg) wrote:
>
> > Why are names in unnamed namespaces used as template parameters treated
> > the same from different files' unnamed namespaces? Translation: If two
> > somethings (function, object, class) in in two different unnamed
> > namespaces in different files have the same name and are used to
> > instantiate a template, the template isn't generated for both versions.
> > unnamed namespaces, as I understand them, are equivalent to a
> > uniquely-named namespace that has an implicit using declaration for the
> > file. It seems Code Warrior Pro 4 does not get the uniquely-named behavior
> > correct, so this problem occurs:
> >
> >
> > // file common.h
> >
> > #include <assert.h>
> >
> > // call a function, passed as template parameter
> > template<int (*F)()>
> > int call_func() { return F(); }
> >
> > void func_in_other_file();
> >
> > // file test.cpp
> >
> > #include "common.h"
> >
> > namespace {
> > int f() { return 1; }
> > }
> >
> > int main()
> > {
> > assert( call_func<f>() == 1 );
> > func_in_other_file();
> > }
> >
> > // file test2.cpp
> >
> > #include "common.h"
> >
> > namespace {
> > int f() { return 2; }
> > }
> >
> > void func_in_other_file()
> > {
> > assert( call_func<f>() == 2 );
> > }
> >
> >
> > With regard to templates, it is like the compiler is just treating *all*
> > unnamed namespaces in all files as one namespace:
> >
> > // file 1
> >
> > namespace unnamed { /* ... */ };
> > using namespace unnamed;
> >
> > // file 2
> >
> > namespace unnamed { /* ... */ };
> > using namespace unnamed;
> >
> > Not good!
> >
> > If you change the template function to accept a class type, and modify the
> > test to validate accordingly, the same thing happens; only one version of
> > the template is kept during linking.
> >
> > Is this fixed in the update? I seem to rememer similar problems mentioned
> > for unnamed namespaces in general, even without templates, in earlier
> > versions of the compiler.
>
> This example is not legal C++ code. C++ only allows objects/functions with
> external linkage in C++ template non-type arguments and unnamed namespace
> members do not have external linkage.
>
> The compiler should print an error for this we will try to fix this for Pro 5.
Here is a relevant quote for the *CD2* draft of the standard (I don't have
the final standard due to problems getting it from ANSI, but something
this basic shouldn't have changed):
> 7.3.1.1 Unnamed namespaces [namespace.unnamed]
>
> 1 An unnamed-namespace-definition behaves as if it were replaced by
> namespace unique { /* empty body */ }
> using namespace unique;
> namespace unique { namespace-body }
> where all occurrences of unique in a translation unit are replaced by
> the same identifier and this identifier differs from all other identi-
> fiers in the entire program.5) [Example:
> namespace { int i; } // unique::i
> void f() { i++; } // unique::i++
>
> namespace A {
> namespace {
> int i; // A::unique::i
> int j; // A::unique::j
> }
> void g() { i++; } // A::unique::i++
> }
> using namespace A;
> void h() {
> i++; // error: unique::i or A::unique::i
> A::i++; // A::unique::i
> j++; // A::unique::j
> }
> --end example]
This is the a big reason unnamed namespaces are better than static entities:
they can be used in templates, and everywhere else as normal, but there is
no worry (with a compiler that implements them correctly) that the names
will clash with any other ones in other files in the program.
So now the compiler isn't going to even accept templates using unnamed
namespaces? I hope not! This would really suck.
[comp.std.c++ members - please verify if this is correct or not - thanks]
--
Gargantua Blargg | blargg@flash.net | http://www.flash.net/~blargg/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/12/19 Raw View
blargg@flash.net (Gargantua Blargg) writes:
>In article
><MWRon-1812981730570001@dyn1-tnt1-244.kalamazoo.mi.ameritech.net>,
>MWRon@metrowerks.com (MW Ron) wrote:
>> In article <blargg-1712981238210001@p119.amax18.dialup.aus1.flash.net>,
>> blargg@flash.net (Gargantua Blargg) wrote:
>>
>> > Why are names in unnamed namespaces used as template parameters treated
>> > the same from different files' unnamed namespaces? Translation: If two
>> > somethings (function, object, class) in in two different unnamed
>> > namespaces in different files have the same name and are used to
>> > instantiate a template, the template isn't generated for both versions.
>> > unnamed namespaces, as I understand them, are equivalent to a
>> > uniquely-named namespace that has an implicit using declaration for the
>> > file.
I think the compiler is wrong. More below.
>> This example is not legal C++ code. C++ only allows objects/functions with
>> external linkage in C++ template non-type arguments and unnamed namespace
>> members do not have external linkage.
>>
>> The compiler should print an error for this we will try to fix this for Pro 5.
I don't find anything in the standard that says entities in unnamed
namespaces CANNOT have external linkage. On the other hand, 3.5 says
that, for example, named classes, non-const objects, and functions
at namespace scope DO have external linkage unless declared static.
(It doesn't say "except for unnamed namespaces", although it does
mention unnamed namespaces in some contexts.)
Furthermore, 7.3.1.1 mentions in a footnote that entities in an
unnamed namespace might have external linkage. (Not everthing in a
namespace has external linkage, hence "might".)
It is then up to the compiler to generate unique external names
for things in an unnamed namespaces, so that the same names in
different unnamed namespaces do not refer to the same thing,
even when their linkage is external.
Most current compilers take the shortcut of giving things in
unnamed namespaces internal linkage, as if they were "static".
This shortcut removes the need to generate unique names, but
doesn't allow use of entities in unnamed namespaces as template
actual parameters.
Gargantua said in a private communication that I said in some
earlier article that members of unnamed namespaces had internal
linkage. If I said that, I was wrong.
--
Steve Clamage, stephen.clamage@sun.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: blargg@flash.net (Gargantua Blargg)
Date: 1998/12/20 Raw View
In article <75gmv3$pnt$1@engnews2.Eng.Sun.COM>, stephen.clamage@sun.com
(Steve Clamage) wrote:
> blargg@flash.net (Gargantua Blargg) writes:
>
> >In article
> ><MWRon-1812981730570001@dyn1-tnt1-244.kalamazoo.mi.ameritech.net>,
> >MWRon@metrowerks.com (MW Ron) wrote:
>
> >> In article <blargg-1712981238210001@p119.amax18.dialup.aus1.flash.net>,
> >> blargg@flash.net (Gargantua Blargg) wrote:
> >>
> >> > Why are names in unnamed namespaces used as template parameters treated
> >> > the same from different files' unnamed namespaces? Translation: If two
> >> > somethings (function, object, class) in in two different unnamed
> >> > namespaces in different files have the same name and are used to
> >> > instantiate a template, the template isn't generated for both versions.
> >> > unnamed namespaces, as I understand them, are equivalent to a
> >> > uniquely-named namespace that has an implicit using declaration for the
> >> > file.
>
> I think the compiler is wrong. More below.
>
> >> This example is not legal C++ code. C++ only allows objects/functions with
> >> external linkage in C++ template non-type arguments and unnamed namespace
> >> members do not have external linkage.
> >>
> >> The compiler should print an error for this we will try to fix this
for Pro 5.
>
> I don't find anything in the standard that says entities in unnamed
> namespaces CANNOT have external linkage. On the other hand, 3.5 says
> that, for example, named classes, non-const objects, and functions
> at namespace scope DO have external linkage unless declared static.
> (It doesn't say "except for unnamed namespaces", although it does
> mention unnamed namespaces in some contexts.)
>
> Furthermore, 7.3.1.1 mentions in a footnote that entities in an
> unnamed namespace might have external linkage. (Not everthing in a
> namespace has external linkage, hence "might".)
>
> It is then up to the compiler to generate unique external names
> for things in an unnamed namespaces, so that the same names in
> different unnamed namespaces do not refer to the same thing,
> even when their linkage is external.
I see unnamed namespaces as being a "superior alternative to static" (a
quote from the standard). They are meant to allow all the things you can
normally have external, internal to the file, without any special syntax
(other than putting them in the unnamed namespace). This includes being
used in templates, something that isn't possible for static
functions/objects and non-uniquely-named classes. Intuitively it makes
sense that an unnamed namespace is simply a named namespace with a unique
name in the whole program, with an implicit using directive to make it
available to the entire file.
> Most current compilers take the shortcut of giving things in
> unnamed namespaces internal linkage, as if they were "static".
> This shortcut removes the need to generate unique names, but
> doesn't allow use of entities in unnamed namespaces as template
> actual parameters.
The reason being, of course, to lighten the load on the linker, since most
objects in an unnamed namespace won't ever be used by the linker outside
the file, except those used by templates where the template isn't
generated during compilation of the file.
Are templates the only way a conforming program can determine if a
compiler is (incorrectly) performing the optimization of giving unnamed
namespace members internal linkage? I can't think of anything else offhand
that would be behave differently.
Again, this sucks because it elimiates one of the convenient reasons to
use an unnamed namespace (instantiating templates on names from the
namespace). Without them, or a correct implementation of them, you still
have to resort to names like Filename_prefix_func_name and
Filename_prefix_class_name, or wrapping them in a namespace with a unique
name, to prevent clashes with names in other file.
> Gargantua said in a private communication that I said in some
> earlier article that members of unnamed namespaces had internal
> linkage. If I said that, I was wrong.
I'm sorry, there was a miscommunication. The quote I found in an article
actually was correct and agreed with the above. Though you mentioned you
had made this mistake sometime prior, before you noticed the part about
names being able to be used with templates, therfore needing to be
external.
--
Gargantua Blargg | blargg@flash.net | http://www.flash.net/~blargg/
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/12/21 Raw View
On 20 Dec 1998 18:12:21 GMT, Gargantua Blargg <blargg@flash.net> wrote:
[Discussing why entities in unnamed namespaces are superior to
entities declared static].
Note that only objects and non-member functions can be static.
But you can put anything in unnamed namespaces -- class
definitions, member functions, non-member functions, objects.
So unnamed namespaces are better from a theoretical point of
view: they allow you to give anything the effect of internal
linkage, whereas 'static' allows you to give only non-member
functions and objects the effect of internal linkage.
>The reason being, of course, to lighten the load on the linker, since most
>objects in an unnamed namespace won't ever be used by the linker outside
>the file, except those used by templates where the template isn't
>generated during compilation of the file.
Good reason.
One reason why functions in unnamed namespaces are superior to static
functions is to make long distance friendship a little safer.
In the past, one the reasons against long distance friendship was
that it could be used to gain access to the interals of a class.
Here is an example:
// Priority.h
class Priority
{
friend bool operator==(Priority lhs, Priority rhs);
public: enum Enum { LOW, MEDIUM, HIGH }; Priority(Enum);
};
// Priority.c
#include "Priority.h"
bool operator==(Priority lhs, Priority rhs)
{
// the proper definition of this function
}
// Thief1.c
#include "Priority.h"
static bool operator==(Priority lhs, Priority rhs)
{
// can see internals of lhs and rhs
}
// Thief2.c
#include "Priority.h"
inline bool operator==(Priority lhs, Priority rhs)
{
// can see internals of lhs and rhs
}
// main.c
#include "Thief1.h"
#include "Thief2.h"
int main() { ... }
See what's happening? The functions declared in "Thief[12].h" and
defined in "Thief[12].c" use the friend declaration to get access
to the internal details of the class, thereby violating
encapsulation.
The function in "Thief1.c" defines the function as a 'static'
function so that it has internal linkage. This means that at link
time, the definition in "Thief1.o" will not conflict with the proper
definition in "Priority.o". This is one reason why the 'static'
keyword is deprecated in the new standard.
The function in "Thief2.c" defines the function as an 'inline'
function. In the past, inline functions had internal linkage, so
you don't get multiple definition errors at link time. However,
as 'inline' is so useful, it can't be deprecated. So the rule
in the new standard is that inline functions have external
linkage. This should force errors at link time, although I
wonder how many compilers actually do this.
In short, the old reason that long distance friendship violates
encapsulation because someone can steal the friendship is no
longer valid. But the other reason against long distance
friendship remains: it leads to designs that are harder to
comprehend, harder to keep straight in our minds.
However, good design says that a friend function declared in
SOMEFILE.H should be defined in the file SOMEFILE.C. Provided
we only use this kind of long distance friendship, we should
be ok. (See Lakos for details).
--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/21 Raw View
In article <slrn77qrbb.i0h.sbnaran@localhost.localdomain>, Siemel Naran
<sbnaran@localhost.localdomain.COM> writes
>However, good design says that a friend function declared in
>SOMEFILE.H should be defined in the file SOMEFILE.C. Provided
>we only use this kind of long distance friendship, we should
>be ok. (See Lakos for details).
Sorry, but I must be dense today because I cannot see how unnamed
namespaces help with this problem. Exactly how am I going to declare
friendship to a function in an unnamed namespace? Other than with a
class in that same namespace, which then cannot be defined/used anywhere
other than in the same translation unit.
And declaring friendship in a named namespace buys nothing because
namespaces can be re-opened.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]