Hi Hermann-Josef,
On Tue, 29 Jan 2002 13:43:20 +0100 (CET)
"mathes@ik.fzk.de" <mathes@ik3.fzk.de> wrote
concerning "Re: [ROOT] Unresolved reference and CINT":
>
> Hi Christian,
>
> thanks for the reply. Your suggestion was not what I indended to do but it
> helped me anyway ...
>
> I wanted to have a constant in the 'namespace' of the class TEyeEventHeader
> and use it outside of this class as TEyeEventHeader::kTicksPerSecond.
> That is the reason why it was not named fgTicksPerSecond.
>
> Well an appropriate solution could be:
>
> class TEyeEventHeader : public TObject {
> public:
> enum Constants {
> kTicksPerSecond = 100000000
> };
>
> ClassDef(TEyeEventHeader,(int)EyeEVENTVERSIONv1)
> };
>
> or what do you think ?
If your member is indeed of `integer' type (short, int, or long),
then you can use an `enum'. However, the above actually introduces
another name space, since you've given the `enum' a name. Consider
#include <iostream>
class Foo
{
private:
public:
enum Bar {
kBar = 100000
};
enum {
kBaz = 1000000000
};
};
void Print(Foo::Bar bar) {
cout << "Foo::Bar enumerator: " << bar << endl;
}
void Print(int baz) {
cout << "int: " << baz << endl;
}
int main(int argc, char** argv)
{
Print(Foo::kBar);
Print(Foo::kBaz);
return 0;
}
Compiling an running this gives:
Foo::Bar enumerator: 100000
int: 1000000000
so there's a difference between the two kinds of `enum'. The named
`enum' diffines a type, while the unnamed defines a bit field (I
think). Therefor, I suggest you use an unnamed `enum' if you want to
use `TEyeEventHeader::kTicksPerSecond' as a `integer' constant, rather
than a `TEyeEventHeader::Constants' value.
> Probably declaration and definition of the member variable is
> something which is not generally allowed ?
What do you mean? In section 9.2, paragraph 4, it says
A member-declarator can contain a constant-initializer only if it
declares a static member (9.4) of inte-gral or enumeration type, see
9.4.2.
in Section 9.4.2, paragraph 4, it says
If a static data member is of const integral or const enumeration
type, its declaration in the classdefinition can specify a
constant-initializer which shall be an integral constant expression
(5.19). In thatcase, the member can appear in integral constant
expressions within its scope. The member shall still be defined in
a namespace scope if it is used in the program and the namespace
scope definition shall not contain an initializer.
So, doing
#include <iostream>
class Foo
{
public:
static const int fgFoo = 10;
};
main(int argc, char** argv)
{
return Foo::fgFoo;
}
is ok - hmm, which sort of begs the original question. I tried the
above code using GCC versions 2.91.66, RedHat-2.96, and 3.0.2, and it
worked fine. However, if I instead have the files foo.hh, foo.cc, and
main.cc with the contents
// foo.hh
class Foo {
public:
static const fgFoo = 10;
Foo();
};
// EOF
// foo.cc
Foo::Foo() {}
// EOF
// main.cc
#inlcude "foo.hh"
main(int argc, char** argv)
{
return Foo::fgFoo;
}
// EOF
and I compile the class to a shared library,
g++ -c -fPIC -Wall foo.cc
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o
g++ -L. -lfoo -Wl,-rpath,. main.cc -o foo
then listing the symbols in libfoo.so and foo (using nm -C) does not
show Foo::fgFoo, and I guess that's why the linker can't find in your
case. However, moving the initialisation of fgFoo to foo.cc makes
Foo::fgFoo visible in libfoo.so. I can't tell you why the above
example works and yours doesn't. It seems the compiler does some
inline substitution of the `static const' member or something. Why
that doesn't work in your case, I don't know.
Anyway, to get back to your statement above, the following is _not_
legal code:
class Bar {
public:
const int kBar = 10;
};
GCC complains, and asks you to make Bar::kBar static.
Yours,
Christian Holm Christensen -------------------------------------------
Address: Sankt Hansgade 23, 1. th. Phone: (+45) 35 35 96 91
DK-2200 Copenhagen N Cell: (+45) 28 82 16 23
Denmark Office: (+45) 353 25 305
Email: cholm@nbi.dk Web: www.nbi.dk/~cholm
This archive was generated by hypermail 2b29 : Sat Jan 04 2003 - 23:50:40 MET