Topic: static deprecated ?
Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/06/15 Raw View
In article <3r7asm$p9g@hpsystem1.informatik.tu-muenchen.de>,
Ulf Schuenemann <schuenem@informatik.tu-muenchen.de> wrote:
>
>
>9.6 Unions [class.union] 3:
>> Anonymous unions declared at namespace scope shall be declared static.
>
>7.3.1.3 Namespacescope [namespace.scope] 3:
>> The use of the static keyword is deprecated when declaring objects
>> in a namespace scope.
>
>I conclude from that, that anonymous unions are not objects.(?)
>
>
>Is this the complete list of where the static keyword is allowed
>and not deprecated?
>
>1. static memberfunctions and membervariables at classscope
>2. anonymous unions at namespacescope
>3. static variables at functionsscope
No, (2) is also deprecated. This makes anonymous
unions at namespace scope deprecated.
The rule that "static" is deprecated has some serious
problems. It may be changed: be wary. Namespaces don't quite
work as they should, and the anonymous namespace is NOT
equivalent to a static:
1) The anonymous namespace is a scope
void f(int);
static void f(long);
static h() { ..f(1); f(1L); }
void f(int);
namespace {
void f(long);
void h() { ..f(1); f(1L); } // WOOPS
}
2) the implicit using directive doesn't work with qualification:
static void f();
class X { void f() { ::f(); } };
namespace { void f(); }
class X { void f() { ::f(); } }; // WOOPS
3) the implicit using directive doesn't work with
using declarations
namespace X { static int x; }
void g() { X::x; }
namespace X { namespace { int x; } }
void g() { X::x; } // WOOPS
Recently, as part of an awareness of these problems, Bjarne
proposed a change in the lookup rules for qualification
so that it "followed" using directives; and example (3) would work.
The proposal was rejected.
I have to say I'm not too happy about namespaces. There is no
easy way to properly synthesise a namespace, and the way that
appears to work is "incoherent" as follows:
namespace A { int a; }
namespace B { int b; }
namespace C {
using namespace A;
using namespace B;
}
using namespace C;
void f() {
a++; // OK
A::a++; // OK
C::a++; // WOOPS
}
It is my opinion -- and the Metaware namespace implementation
agrees with me -- that using directives should NOT be transitive.
That is, they are there to make resources available for
defining entities of a namespace and NOT to make those entities
available to clients of the namespace. So in the example
above:
a++; // WOOPS
-- which is consistent with "C::a++; // WOOPS".
I also proposed using inheritance for synthesis:
namespace C : A, B {}
as a superior and well understood mechanism. Note that this
does NOT cause overloading across the base spaces as
using directives would. Note that qualification
"follows" bases automatically (as in classes, it acts as
a scope override).
[I think this is clearly the best solution but many people do
not agree and others are more concerned to standardise
something "ASAP" whether it works properly or not.
Such resistance to change can only be broken by a public outcry]
[Metaware implements:
using A::*;
using B::*;
to solve this problem (since it has intransitive using
directives). Few committee members like this much,
especially the syntax]
I personally believe that an adequate synthetic "command set"
is necessary because it is my view that "systems programmers"
-- who are specialists in larger organisations -- will
spend a lot of time defining and implementing namespaces
to _corporate_ standards. It will be their job to
take various libraries and interface them transparently
for application programmers.
A trivial (and silly) example:
namespace FooCorp_Maths {
using std::sin;
using NumericalRecipies::cos;
}
To do this kind of work effectively requires much more control
than the existing namespace features provide. (Think about
controlling overload sets).
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd,
81A Glebe Point Rd, GLEBE Mem: SA IT/9/22,SC22/WG21
NSW 2037, AUSTRALIA Phone: 61-2-566-2189