C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

static definiitions

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
LuB
Guest





PostPosted: Sun Aug 13, 2006 8:35 pm    Post subject: static definiitions Reply with quote



I have written a library with only template .hpp files. OT but if it
helps, modelled after Microsoft's WTL or ATL library.

Now I'd like to create a class with nothing but constants. In this
case, it is simply a class of colors. The members should be static. Is
there a way to declare and define these in the same file (or spot)
without artificially creating a template.

I thought the following was illegal - or could pose problems down the
road - but it seems to compile just fine for me now. If this is legal -
then that is answer to my post.

// compiles under MSVC 8

struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};

const COLORREF Colors::BG = RGB(0x33, 0x33, 0x33);

const COLORREF Colors::FG = RGB(0xe1, 0xe1, 0xe1);


If the above snippet is NOT legal or unsafe, then please read on.




// obviously illegal - but optimum syntax
// for what I'm trying to achieve.

struct Colors
{
static const COLORREF BG = RGB(0x33, 0x33, 0x33);
static const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);
};



// This approach (all in the same file)
// is legal, works and doesn't require an explicit template
// parameter when I use the class -
// but I don't like the artificial template declaration.
// It creates a bit of confusion.

template<typename T = int>
struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};

template<typename T>
const COLORREF Colors<T>::BG = RGB(0x33, 0x33, 0x33);

template<typename T>
const COLORREF Colors<T>::FG = RGB(0xe1, 0xe1, 0xe1);


// I guess I could always globally declare
// these variables in a new namespace.
// This does indeed serve my objective
// but these are now global and hopefully avoidable.

namespace style {

const COLORREF BG = RGB(0x33, 0x33, 0x33);

const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);

}


Thanks in advance,

-Luther


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





PostPosted: Mon Aug 14, 2006 5:52 pm    Post subject: Re: static definiitions Reply with quote



LuB wrote:
Quote:
I have written a library with only template .hpp files. OT but if it
helps, modelled after Microsoft's WTL or ATL library.

Now I'd like to create a class with nothing but constants. In this
case, it is simply a class of colors. The members should be static. Is
there a way to declare and define these in the same file (or spot)
without artificially creating a template.

I thought the following was illegal - or could pose problems down the
road - but it seems to compile just fine for me now. If this is legal -
then that is answer to my post.

// compiles under MSVC 8

struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};

const COLORREF Colors::BG = RGB(0x33, 0x33, 0x33);

const COLORREF Colors::FG = RGB(0xe1, 0xe1, 0xe1);


If the above snippet is NOT legal or unsafe, then please read on.


assuming COLORREF etc. are defined and the definition of FG and BG are
seen once and only once it is legal. However you will get problems if,
for instance somebody includes this header and links against something
else with the definition in. The safest way to deal with that would be
to compile the definitions into a library and have that as the only way
of accessing them - you seem to be going through hoops to explicitly
avoid having a compiled library with you template library though, is
there a good reason for this?


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





PostPosted: Mon Aug 14, 2006 5:53 pm    Post subject: Re: static definiitions Reply with quote



Quote:
// compiles under MSVC 8

struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};

const COLORREF Colors::BG = RGB(0x33, 0x33, 0x33);

const COLORREF Colors::FG = RGB(0xe1, 0xe1, 0xe1);

Perfectly legal AFAIK, given that COLOREF is not illegal. I assume it
is a typedef for unsigned __int32 or a similar 32-bit type suitable for
vanilla ARGB storage. If what you're interested in are static constants
behind a namespace (which is how I interpret the struct surronding
Colors), why not using enums? Compile-time, and no memory footprint:

enum COLORREF
{
BG = 0x00333333,
FG = 0x00e1e1e1
};

Regards,
Michael Andersson


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






PostPosted: Mon Aug 14, 2006 5:54 pm    Post subject: Re: static definiitions Reply with quote

LuB wrote:
Quote:
I have written a library with only template .hpp files. [...]
I thought the following was illegal - or could pose problems down the
road - but it seems to compile just fine for me now. If this is legal -
then that is answer to my post.

// compiles under MSVC 8

struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};
const COLORREF Colors::BG = RGB(0x33, 0x33, 0x33);
const COLORREF Colors::FG = RGB(0xe1, 0xe1, 0xe1);

Not legal, violates ODR, 3.2/3, if this header is included more than
once.

Quote:


// obviously illegal - but optimum syntax
// for what I'm trying to achieve.

struct Colors
{
static const COLORREF BG = RGB(0x33, 0x33, 0x33);
static const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);
};

This is legal assuming all the following are true:
1) COLORREF is an integer type and RGB is ICE (true with msvc8) and
2) The compiler is new enough (msvc8 is) and
3) The program never uses the address of BG or FG.

Quote:
// I guess I could always globally declare
// these variables in a new namespace.
// This does indeed serve my objective
// but these are now global and hopefully avoidable.

namespace style {
const COLORREF BG = RGB(0x33, 0x33, 0x33);
const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);
}

This also violates ODR.

Another approach is to make these inline functions, rather than
variables.
struct Colors
{
static COLORREF BG(){ return RGB(0x33, 0x33, 0x33); }
...
};


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





PostPosted: Mon Aug 14, 2006 5:54 pm    Post subject: Re: static definiitions Reply with quote

LuB wrote:
Quote:

I thought the following was illegal - or could pose problems down the
road - but it seems to compile just fine for me now. If this is legal -
then that is answer to my post.

// compiles under MSVC 8

struct Colors
{
static const COLORREF BG;
static const COLORREF FG;
};

const COLORREF Colors::BG = RGB(0x33, 0x33, 0x33);

const COLORREF Colors::FG = RGB(0xe1, 0xe1, 0xe1);

This should be legal. However, every translation unit is likely to
have it's own copies of Colors::BG and Colors::FG.

Quote:
// obviously illegal - but optimum syntax
// for what I'm trying to achieve.

struct Colors
{
static const COLORREF BG = RGB(0x33, 0x33, 0x33);
static const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);

};

This should be legal too as long as you are not taking the address of
Colors::BG or Colors::FG. In the latter case you are likely to end up
with the linker complaining about undefined reference(s).

Not pretty sure, but 'static int const' (and other enumerated types)
are compile-time only objects. They are substituted just like:

#define COLORS_BG RGB(...)
#define COLORS_FG RGB(...)


Alex


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





PostPosted: Mon Aug 14, 2006 9:46 pm    Post subject: Re: static definiitions Reply with quote

wade (AT) stoner (DOT) com wrote:

Quote:
Not legal, violates ODR, 3.2/3, if this header is included more than
once.

therfore until it is included more than once it *is* legal, you may not
consider it advisable however due to the risk of unwittingly breaking
the ODR.


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





PostPosted: Tue Aug 15, 2006 5:43 am    Post subject: Re: static definiitions Reply with quote

wade (AT) stoner (DOT) com wrote:
Quote:
LuB wrote:
namespace style {
const COLORREF BG = RGB(0x33, 0x33, 0x33);
const COLORREF FG = RGB(0xe1, 0xe1, 0xe1);
}

This also violates ODR.

These const declarations for BG and FG do not violate the One
Definition Rule. Because const declarations have (by default) internal
linkage - it's not possible for one source file to refer to the BG or
FG variable that is used in another source file. Therefore each source
file that includes this header effectively has their own, private BG
and FG variables - just as if each source file had declared their own
static, BG and FG variables (a deprecated technique that also does not
violate the ODR).

Greg


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





PostPosted: Fri Aug 18, 2006 6:00 pm    Post subject: Re: static definiitions Reply with quote

{ extraneous whitespace removed. -mod }

LuB wrote:
Quote:
I have written a library with only template .hpp files. OT but if it
helps, modelled after Microsoft's WTL or ATL library.

Now I'd like to create a class with nothing but constants. In this
case, it is simply a class of colors. The members should be static. Is
there a way to declare and define these in the same file (or spot)
without artificially creating a template.

Thanks to everyone who replied. I never really understood the notion of
'compilation unit' but it seems quite obvious now. It brings to mind a
different, underlying question (and JK is correct, I am trying to avoid
creating an actual library - but not adamantly)

// declared and defined in same file - illegal
// (at least for the obvious case - I *would* be including this in
multiple files)

struct Foo
{
static std::string WindowClassName;
};

std::string Foo::WindowClassName("name");

But because the following _can_ be housed in one file, I suddenly
realized the compiler *CAN* handle single files with static class
values declared and defined and I wondered if there was a way to
motivate the compiler to be just so gentle with the illegal case above.

I do realize that templates are indeed a special case ... and maybe
that's the end of it.

template<typename T>
struct Foo
{
static std::string WindowClassName;
};

template<typename T>
std::string
Foo<T>::WindowClassName("arbitraryname");

I believe this works because the compiler is explicitly written to
handle just such a declaration/definition. I just wasn't sure why
similar compiler logic could not also be available to handle the
original, illegal case .... admittedly, this is a bit esoteric.

Thanks,

-Luther


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.