constants within a namespace

F

forums_mp

Given a file global constants.h such that:

//global_constants.h
namespace GlobalConstants {
int const X = 5;
double const PI = 3.141 ;
}


During an email exchange with a coworker the coworker made the claim
that the constants will be repeated in memory for each code object
file that includes it. So if there's alot of constants that are used
everywhere, I will consume lots of memory.

Now consider a class X such that:

# include "global_constants.h"

class X {
public :
X ()
void do_work()
{ int const dummy = GlobalConstants::X ; }
};

Two things:
a) I thought elimination of unused symbols was guaranteed (couldn't
confirm this in the standard though). IOW PI will be non-existent in
the object file for X.
b) I've often understood that no 'memory' will be consumed anywhere
since GlobalConstants::X will be replaced with the value 5. Memory is
consumed within the namespace for sizeof ( int ) and sizeof (double)
but that's the extent of it for the GlobalConstants.

Am I off on a) and b) above? Thanks in advance
 
Ö

Öö Tiib

Given a file global constants.h such that:

//global_constants.h
namespace GlobalConstants {
  int  const X = 5;
  double const PI = 3.141 ;

}

During an email exchange with a coworker the coworker made the claim
that the constants will be repeated in memory for each code object
file that includes it.  So if there's alot of constants that are used
everywhere, I will consume lots of memory.

Your coworker is right that such constants have internal linkage (as
objects that are explicitily declared const and neither previously nor
explicitily declared extern). But you should not worry since compilers
usually optimize out what they only can.
Now consider a class X such that:

# include "global_constants.h"

class X {
public :
  X ()
  void do_work()
  {  int const dummy = GlobalConstants::X ; }

};

Two things:
a)  I thought elimination of unused symbols was guaranteed (couldn't
confirm this in the standard though).  IOW PI will be non-existent in
the object file for X.

Yes, simple const objects with internal linkage that are not used will
be usually just eliminated by compiler. Simple const objects with
external linkage used nowhere can also be eliminated by linker. There
are issues with not too simple objects. For example const objects that
have complex constructors or destructors with possible side effects
are assumed to be possibly defined especially for running the
constructors or destructors and so can not be eliminated.
b)  I've often understood that no 'memory' will be consumed anywhere
since GlobalConstants::X will be replaced with the value 5.  Memory is
consumed within the namespace for sizeof ( int ) and sizeof (double)
but that's the extent of it for the GlobalConstants.

This is also usually done, unless compiler can not do it. For example
compiler can not do it at places where your code takes pointer to
GlobalConstants::X or passes it by reference to some function. Pointer
to GlobalConstants::X has to point to something and pointer taken will
be different for each compilation unit that includes
global_constants.h.
Am I off on a) and b) above?  Thanks in advance

I think you are on right track. There are lots of special cases that
do not matter with simple types like floats and ints.
 
F

forums_mp

Your coworker is right that such constants have internal linkage (as
objects that are explicitily declared const and neither previously nor
explicitily declared extern). But you should not worry since compilers
usually optimize out what they only can.

Ok so given:

//.h
class GlobalConstants {
public :
static int const X = 5 ;
static double const PI ;
};
//.cpp
double const GlobalConstants::pI = 3.141;

Could I make the same argument?
i.e. "the constants will be repeated in memory for each code object
file that includes it. So if there's alot of constants that are used
everywhere, I will consume lots of memory"

Trying to understand what the 'recommended alternative' buys me. In
my view the issue is the same namespace or class.
This is also usually done, unless compiler can not do it. For example
compiler can not do it at places where your code takes pointer to
GlobalConstants::X or passes it by reference to some function. Pointer
to GlobalConstants::X has to point to something and pointer taken will
be different for each compilation unit that includes
global_constants.h.

Meaning if I modified my do_work function such that:

namespace GlobalConstants {
int const X = 5;
double const PI = 3.141 ;
}
class X {
public :
X () {}
void do_work()
{ int const dummy = GlobalConstants::X ;;
double const* pdummy = &GlobalConstants::pI ;
}
};

In this case the compiler is unable to replace the value PI with the
value 3.141. So what happens instead?

Thanks
 
A

Alf P. Steinbach

* (e-mail address removed):
[someone]
Your coworker is right that such constants have internal linkage (as
objects that are explicitily declared const and neither previously nor
explicitily declared extern). But you should not worry since compilers
usually optimize out what they only can.

Your nick sucks and your quoting style, removing attributions, is extremely
annoying.

Ok so given:

//.h
class GlobalConstants {
public :
static int const X = 5 ;
static double const PI ;
};
//.cpp
double const GlobalConstants::pI = 3.141;

Could I make the same argument?
i.e. "the constants will be repeated in memory for each code object
file that includes it. So if there's alot of constants that are used
everywhere, I will consume lots of memory"
No.


Trying to understand what the 'recommended alternative' buys me.

Your style of referring to undefined things is extremely annoying.

In
my view the issue is the same namespace or class.

Your style of referring to undefined things is extremely annoying.


Your style of referring to undefined things is extremely annoying.

For example

Your style of referring to undefined things is extremely annoying.

Pointer

Meaning if I modified my do_work function such that:

namespace GlobalConstants {
int const X = 5;
double const PI = 3.141 ;

Don't use all uppercase names except for macros (see various FAQs).

}
class X {
public :
X () {}
void do_work()
{ int const dummy = GlobalConstants::X ;;
double const* pdummy =&GlobalConstants::pI ;
}
};

In this case the compiler is unable to replace the value PI with the
value 3.141.

That's a pretty weird conclusion, using the term "this case" but relating as it
does to some code that you haven't shown where the PI value presumably is used.

Your style of referring to undefined things is extremely annoying.

Yes, I see what you've written leading up to that conclusion. But none of it
makes sense to me, and nothing of it seems even halfway relevant, sorry. It's
just extremely annoying.

So what happens instead?

Your premise is wrong; what you're talking about (if anything) is undefined.


Cheers,

- Alf
 
F

forums_mp

* (e-mail address removed):
[someone]
Your coworker is right that such constants have internal linkage (as
objects that are explicitily declared const and neither previously nor
explicitily declared extern). But you should not worry since compilers
usually optimize out what they only can.

Your nick sucks and your quoting style, removing attributions, is extremely
annoying.
So does your name.
Your style of referring to undefined things is extremely annoying.

Read again. I'm simply trying to weigh the pros and cons of placing
constants within a namespace versus public members of a class - the
alternative recommendation.

[snip]
 
V

Vladimir Jovic

Read again. I'm simply trying to weigh the pros and cons of placing
constants within a namespace versus public members of a class - the
alternative recommendation.

Where and how you place your constant doesn't matter. What your friend
told you is a nonsense. If you add and use constants, your program size
will increase (off course), but what is an alternative? Only not to use
constants
 
V

Vladimir Jovic

Vladimir said:
Where and how you place your constant doesn't matter. What your friend
told you is a nonsense. If you add and use constants, your program size
will increase (off course), but what is an alternative? Only not to use
constants


Forgot the example.

If you decide to remove constants to save the binary size and memory
usage will drop, this example :

#include <iostream>
int main()
{
for ( int i = 0; i < 5; ++ i )
{
std::cout<<"Hello world!"<<std::endl;
}
}

will have to be transformed to this:

#include <iostream>
int main()
{
for ( ; ; )
{
std::cout<<std::endl;
}
}
 
M

Michael Tsang

Vladimir said:
Forgot the example.

If you decide to remove constants to save the binary size and memory
usage will drop, this example :

#include <iostream>
int main()
{
for ( int i = 0; i < 5; ++ i )
{
std::cout<<"Hello world!"<<std::endl;
}
}

will have to be transformed to this:

#include <iostream>
int main()
{
for ( ; ; )
{
std::cout<<std::endl;
}
}

In this case, 0 and 5 aren't objects. They are just values so that they are
embedded in the assembly outputted but not in read-only memory.
 
F

forums_mp

Where and how you place your constant doesn't matter. What your friend
told you is a nonsense. If you add and use constants, your program size
will increase (off course), but what is an alternative? Only not to use
constants- Hide quoted text -

The alternative/recommended form according to him is to put global
constatns in a class (as opposed to a namespace). i.e:

//.h
class GlobalConstants {
public :
static int const X = 5 ;
static double const PI ;
};
//.cpp
double const GlobalConstants::pI = 3.141;


With my approach:
namespace GlobalConstants {
int const X = 5;
double const PI = 3.141 ;
}

I'll end up with defined objects X and PI in every module (since the
members are declared constant and have internal linkage) even if the
module used one and only one of the object.
For a while, I thought elimination of unused symbols was a guarantee
within the standard but I was wrong. I also thought his recommended
form ( a class ) would result in a defined object in every module. I
was wrong. Long story short, it appears the namespace approach is a
QOI issue.
 
A

Alf P. Steinbach

The alternative/recommended form according to him is to put global
constatns in a class (as opposed to a namespace). i.e:

//.h
class GlobalConstants {
public :
static int const X = 5 ;
static double const PI ;
};
//.cpp
double const GlobalConstants::pI = 3.141;


With my approach:
namespace GlobalConstants {
int const X = 5;
double const PI = 3.141 ;
}

I'll end up with defined objects X and PI in every module (since the
members are declared constant and have internal linkage) even if the
module used one and only one of the object.
For a while, I thought elimination of unused symbols was a guarantee
within the standard but I was wrong. I also thought his recommended
form ( a class ) would result in a defined object in every module. I
was wrong. Long story short, it appears the namespace approach is a
QOI issue.

You can always force elimination, within the language rules, if you want that,
without using separate compilation, that is, with the constants (of any types)
defined in the header file.

And this involves putting the constants a class template, which I guess
misleadingly can be described as "in a class".

Goes like (in a header file)

template< Dummy >
struct GlobalConstants_
{
int const x;
double const pi;
};

template< Dummy >
int GlobalConstants_<Dummy>::x = 5;

template< Dummy >
double GlobalConstants_<Dummy>::pi = 3.141;

typedef GlobalConstants_<void> GlobalConstants;


But it's not like it's context-independently "recommended" or anything, or like
any other way of defining constants is context-independently "recommended".

It's just a solution where you do not want a separately compiled file and you do
want guaranteed elimination and/or extern linkage.


Cheers & hth.,

- Alf
 
F

forums_mp

You can always force elimination, within the language rules, if you want that,
without using separate compilation, that is, with the constants (of any types)
defined in the header file.

And this involves putting the constants a class template, which I guess
misleadingly can be described as "in a class".

Goes like (in a header file)

     template< Dummy >
     struct GlobalConstants_
     {
         int const x;
         double const pi;
     };

     template< Dummy >
     int GlobalConstants_<Dummy>::x = 5;

     template< Dummy >
     double GlobalConstants_<Dummy>::pi = 3.141;

     typedef GlobalConstants_<void> GlobalConstants;

But it's not like it's context-independently "recommended" or anything, or like
any other way of defining constants is context-independently "recommended".

It's just a solution where you do not want a separately compiled file and you do
want guaranteed elimination and/or extern linkage.
Thanks Alf.

Can you clarify what you are alluding to with 'context-independently
recommend'?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top