By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,315 Members | 1,736 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,315 IT Pros & Developers. It's quick & easy.

Does this allocate memory?

P: n/a
If this is the complete program (ie, the address of the const is never
taken, only its value used) is it likely the compiler will allocate ram for
constantA or constantB? Or simply substitute the values in (as would be
required if I used the hideous, evil, much-abused #define :)

-----------

const int constantA = 10;
static const int constantB = 20;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}

----------

Thanks in advance :)

-Curt

Jul 19 '05 #1
Share this Question
Share on Google+
37 Replies


P: n/a
On Tue, 22 Jul 2003 13:49:30 GMT, Curt <cN****@nSoPrthAarMc.com> wrote:
If this is the complete program (ie, the address of the const is never
taken, only its value used) is it likely the compiler will allocate ram for
constantA or constantB? Or simply substitute the values in (as would be
required if I used the hideous, evil, much-abused #define :)

-----------

const int constantA = 10;
static const int constantB = 20;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}


A good compiler will reject this program since it's ill-formed;
"void main()" is not allowed in a hosted standard C++
implemented (the term "hosted" is the standard's terminology).

A not-so-good compiler will reduce the program to nothing since
it doesn't do anything.

But in general, any constant takes up memory space if it's used
at least once. How much is Quality Of Implementation issue.
Not much more can be said without a more specific context.
Jul 19 '05 #2

P: n/a
"Curt" <cN****@nSoPrthAarMc.com> wrote...
If this is the complete program (ie, the address of the const is never
taken, only its value used) is it likely the compiler will allocate ram for constantA or constantB? Or simply substitute the values in (as would be
required if I used the hideous, evil, much-abused #define :)

-----------

const int constantA = 10;
static const int constantB = 20;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}

----------


It's hard to tell. Existence of 'void main' can force the compiler
reject the entire program. 'main' always returns 'int'. If that's
corrected, an optimising compiler will produce code as if the program
were

int main() {}

because the body of the 'main' has no side effects. So, once the
'main' is made to return 'int', I'd say, no memory is going to be
allocated.

Victor
Jul 19 '05 #3

P: n/a
"Victor Bazarov" <v.********@attAbi.com> wrote in news:vhqgt0eifs2499
@corp.supernews.com:
"Curt" <cN****@nSoPrthAarMc.com> wrote...
If this is the complete program (ie, the address of the const is never
taken, only its value used) is it likely the compiler will allocate ram
for
constantA or constantB? Or simply substitute the values in (as would

be required if I used the hideous, evil, much-abused #define :)

-----------

const int constantA = 10;
static const int constantB = 20;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}

----------


It's hard to tell. Existence of 'void main' can force the compiler
reject the entire program. 'main' always returns 'int'. If that's
corrected, an optimising compiler will produce code as if the program
were

int main() {}

because the body of the 'main' has no side effects. So, once the
'main' is made to return 'int', I'd say, no memory is going to be
allocated.

Victor


I'll assume you're not missing my point on purpose, which is, does the
'static' qualifier compel the compiler to allocate memory for a constant
that is initialized once at runtime and is only used as a #define might
be.
const int constantA = 10;
static const int constantB = 20;

int main( int argn, char *argv[] )
{
for( volatile int i=0; i<constantA ; i++ );
for( volatile int j=0; j<constantB ; j++ );

return 0;
}
Jul 19 '05 #4

P: n/a
> >> const int constantA = 10;
static const int constantB = 20;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}

----------
It's hard to tell. Existence of 'void main' can force the compiler
reject the entire program. 'main' always returns 'int'. If that's
corrected, an optimising compiler will produce code as if the program were

int main() {}

because the body of the 'main' has no side effects. So, once the
'main' is made to return 'int', I'd say, no memory is going to be
allocated.

I'll assume you're not missing my point on purpose, which is, does the
'static' qualifier compel the compiler to allocate memory for a constant that is initialized once at runtime and is only used as a #define might be.
The 'static' keyword does not force the compiler to allocate storage for
that variable. In fact it would make it easier for the compiler not to
allocate storage since static variables only accessible within the
current translation unit. Consequently the compiler can determine with
100% certainty that a variable is not referenced, thus no storage needs
to be allocated for it. Storage for non 'static' variables would have to
be removed by the linker. The fact that the variables in your example
are declared 'const' and that they are initialized in the same
translation unit makes it likely that a optimizing compiler simply
substitutes the variables with their values. In that scenario the
variables in your code are not referenced, thus no storage is needed for
those variables. So my guess is that on most decent optimizing compilers
your program will be optimized to int main(){} without storage for the
variables.

However all of this is a quality of implementation issue and your
compiler&linker may, or may not perform those optimizations. If you
really want to know if which optimizations are performed take a look at
the assembly output of the compiler. Note that this output doesn't tell
you which variables were removed by the linker, so I expect that
constantA still has storage associated with it according to listing,
even though it might very well be removed in the linking stage.
const int constantA = 10;
static const int constantB = 20;

int main( int argn, char *argv[] )
{
for( volatile int i=0; i<constantA ; i++ );
for( volatile int j=0; j<constantB ; j++ );

return 0;
}


Why are you using volatile for a local variable?

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Jul 19 '05 #5

P: n/a
"Curt" <cN****@nSoPrthAarMc.com> wrote...
[...]
I'll assume you're not missing my point on purpose, which is, does the
'static' qualifier compel the compiler to allocate memory for a constant
that is initialized once at runtime and is only used as a #define might
be.


'static' has no effect on the constant. Used with a variable
definition in a global namespace scope, 'static' give it internal
linkage. However, if memory is not allocated, linkage would have
no meaning. 'const' allows the compiler not to allocate memory.
That's the prevailing modifier, I believe. 'static' in this case
is subordinate.

Just as with any other 'const', the compiler may decide to allocate
storage. Or it may decide not to allocate storage.

If you wrote

extern const int theanswer = 42;

then the storage would be allocated for sure. Whether the address
of that storage will be used when you use 'theanswer' in the same
unit is also at the discretion of the compiler. It may decide to
replace any occurrence of 'theanswer' in the code with 42 because
it's a 'const'.

Does this answer your question?

Victor
Jul 19 '05 #6

P: n/a
[...]

Thank you for your response.
const int constantA = 10;
static const int constantB = 20;

int main( int argn, char *argv[] )
{
for( volatile int i=0; i<constantA ; i++ ); for( volatile int j=0;
j<constantB ; j++ );

return 0;
}
}

Why are you using volatile for a local variable?


Because the original responders wanted to tell me how smart they were
about proper c++ rather than answer the obvious question in a meaningful
way. So I composed an equally trivial example that would force code
generation.

As a long-time programmer I am sometimes amused (and dismayed) that such
simple language features ( #define constant 10 ) are universally derided
by acedemia/language purists who insist on type-safe const's, yet are not
sure if it will have the same necessary effect of being replaced with the
literal value.

c++ took the language in a lot of good directions, but went too far in
others, the useless defense of cout vs printf for debugging, for example.

-Curt

Jul 19 '05 #7

P: n/a

"Jingz" <e@spam.com> wrote in message news:pa********************************@spam.com.. .
As a long-time programmer I am sometimes amused (and dismayed) that such
simple language features ( #define constant 10 ) are universally derided
by acedemia/language purists who insist on type-safe const's, yet are not
sure if it will have the same necessary effect of being replaced with the
literal value.


It's not typesafety. 10 is of type int just as if you declared it a const int.
The issue is scoping. What happens when something else in the translation
unit (perhaps something you didn't write) use the term constant:

#define constant 10

struct foo {
int constant;
};
....

Perhaps it's just that you don't understand the language well enough.
Jul 19 '05 #8

P: n/a
On Tue, 22 Jul 2003 14:52:59 -0400, Ron Natalie wrote:

"Jingz" <e@spam.com> wrote in message
news:pa********************************@spam.com.. .
As a long-time programmer I am sometimes amused (and dismayed) that
such simple language features ( #define constant 10 ) are universally
derided by acedemia/language purists who insist on type-safe const's,
yet are not sure if it will have the same necessary effect of being
replaced with the literal value.


It's not typesafety. 10 is of type int just as if you declared it a
const int. The issue is scoping. What happens when something else in
the translation unit (perhaps something you didn't write) use the term
constant:

#define constant 10

struct foo {
int constant;
};
...

Perhaps it's just that you don't understand the language well enough.


Yes I've seen that argument as well, it is equally contrived. You really
have to bend over backwards to show how sane use of #define can be a
problem; your example doesn't even compile. A trivial convention like
using all capital letters for #defined values is all that would be
required.

I'm not going to defend such a practice, nor expouse it. The point I have
often made when instructing junior programmers fresh out of college is
that many textbook problems are solutions to problems that only exist in
textbooks.

"The real world" is an overused phrase, but maintainability is key. Too
often I have read in a trade-journal or commentary about a perfectly
reasonable practice that is "bad' becuase some college professor can
contrive an example that "breaks" is.

Not to open up another can of worms, but inheritance is probobly my
favorite example of a good idea gone bad. Everyone agree is it can be
over/mis used, but I will content that it is almost never a good idea. It
obscures functionality at best, at worst is is an absolutely impenatrable
series of tracing back multiple-inheritance spaghetti when a call goes
bad and needs to be debugged. 'has a' is far superior, necessitating a
dereference and obviating that another block of code is being invoked.
"is a" is almost never justified.

Sure it allows library building, and has a nice touchy-feely OO, but the
fact is it solves a bunch of contrived textbook problems that proper
program design not only bypass, but make easier to understand.

-Curt

Jul 19 '05 #9

P: n/a
"Jingz" <e@spam.com> wrote...
[...]
Not to open up another can of worms, but inheritance is probobly my
favorite example of a good idea gone bad. Everyone agree is it can be
over/mis used, but I will content that it is almost never a good idea. It
obscures functionality at best, at worst is is an absolutely impenatrable
series of tracing back multiple-inheritance spaghetti when a call goes
bad and needs to be debugged. 'has a' is far superior, necessitating a
dereference and obviating that another block of code is being invoked.
"is a" is almost never justified.


I really would like to see you implement polymorphism without
inheritance. Or is polymorphism an overrated "touchy-feely OO"
as well? Would you like to try this discussion in comp.object?

Nobody forces you to use any of the language features. If you
think that 'const' is bogus, don't use it. Inheritance is no
good? Live without it. What I don't understand is the need to
"content" the usability of any feature. Live and let live. Or
is the language too complex for you with all that "spaghetti"
in it? Could it be that you just need to make an effort and
simply learn it?

I hope you don't see this as "over/mis used" typing.

Victor
Jul 19 '05 #10

P: n/a
I know I can't win, you are in quite authoritative company in terms of
people I've argued with about programming paradigms, and I know anyone
reading this agrees with you, not me, but I do feel compelled to stick to
facts.

Microsoft thinks defined like "BOOL" and "WORD" make sense, so I'm not
quite sure invoking problems with their source code is credible. I have
indeed never seen a sane define collide in the manner you suggest happens
"all the time" but if we're going to assume insane programmers then you
can prety much claim anything you choose.

I certainly agree that c++ promotes code cloarity and maintainability, no
question about it, but te fact that it can is often used as a cudgel to
beat code with. Complicated multiple inheritance, templates, and bizzare operator
overloading are automatically easier to maintain? I think not. They CAN
be, but care must be used, as in all programming.

-Curt
On Tue, 22 Jul 2003 16:18:48 -0400, Ron Natalie wrote:

"Jingz" <e@spam.com> wrote in message
news:pa**********************************@spam.com ...
Yes I've seen that argument as well, it is equally contrived.


It's not contrived at all. If you've never seen it, you've never
managed a large project where more than one organization wrote parts of
the code.
You really
have to bend over backwards to show how sane use of #define can be a
problem;


I didn't bend over backwards. This stuff happens all the time. It's
a perennial problem with Microsoft include files for example.
I'm not going to defend such a practice, nor expouse it. The point I
have often made when instructing junior programmers fresh out of
college is that many textbook problems are solutions to problems that
only exist in textbooks.


Sorry, just because YOU have never seen the problem, doesn't mean they
shouldn't exist. Do you advocate telling drivers to not fasten their
seatbelts because you've never been in an accident?
"The real world" is an overused phrase, but maintainability is key.


Precisely. Using C++ constructs promotes maintainability.


Jul 19 '05 #11

P: n/a
> Nobody forces you to use any of the language features. If you think
that 'const' is bogus, don't use it. Inheritance is no good? Live
without it. What I don't understand is the need to "content" the
usability of any feature. Live and let live. Or is the language too
complex for you with all that "spaghetti" in it? Could it be that you
just need to make an effort and simply learn it?


Indeed, if all you took away from my posts was "inheritance is no good"
then one of us does need to take more time and study, and its you.

-Curt

Jul 19 '05 #12

P: n/a
"Jingz" <e@spam.com> wrote...
I really would like to see you implement polymorphism without
inheritance. Or is polymorphism an overrated "touchy-feely OO" as well?


Would be delighted to, show me the example.


I don't think you deserve it, considering the tone you've taken.

class DrawContext;

class Window
{
set<Window*> child_windows;
public:
virtual void draw(const DrawContext&) = 0;
void addChildWindow(Window* pw)
{
child_windows.push_back(pw);
}
};

class OpenGLWindow : virtual public Window
{
void draw(const DrawContext&);
};

class ToolbarWindow : virtual public Window
{
void draw(const DrawContext&);
};

class ThreeDToolbarWindow : public ToolbarWindow, OpenGLWindow
{
...
};

class MainWindow : public Window
{
public:
MainWindow(const string&);
void draw(const DrawContext&);
};

....

class MySpecialMainWindow : public MainWindow
{
public:
MySpecialMainWindow(const string& title) :
MainWindow(title)
{
addChildWindow(new ThreeDToolbarWindow);
}
};

void Window::draw(const DrawContext& dc)
{
set<Window*>::iterator kid_it = child_windows.begin();
while (kid_it != child_windows.end())
{
(*kid_it)->draw(dc);
++kid_it;
}
}

.... Why do I bother? ...

Victor
Jul 19 '05 #13

P: n/a

Victor Bazarov wrote:
... Why do I bother? ...


http://www.uclan.ac.uk/facs/science/...ty/ppsycho.pdf
(see "fixation -> anal personality")

regards,
alexander.
Jul 19 '05 #14

P: n/a
This is not a complete example, this is a code snippet from a larger
system that assumes this functionality is available. Since its clearly
from a very large system I don't think its feasible to show you how it
could be implemented in a far easier to maintain and less obscure way.

What am I talking about? Well, for example, everything thats important
happens as the result of a side-effect of calling "draw". Since the code
is not declarative, you have to hope the implementor thought of
everything when they wrote their piece of the class.

Since, of course, they didn't, you're going to have to go spelunking
through an endless list of header files to find the implementation, and
heaven forbid the original design was flawed, and critical information
was not passed back to a class back at layer 2 or 3. I've seen that and
its not pretty.

-Curt
On Tue, 22 Jul 2003 16:53:37 -0400, Victor Bazarov wrote:
class DrawContext;

class Window
{
set<Window*> child_windows;
public:
virtual void draw(const DrawContext&) = 0; void
addChildWindow(Window* pw)
{
child_windows.push_back(pw);
}
};

class OpenGLWindow : virtual public Window {
void draw(const DrawContext&);
};

class ToolbarWindow : virtual public Window {
void draw(const DrawContext&);
};

class ThreeDToolbarWindow : public ToolbarWindow, OpenGLWindow {
...
};

class MainWindow : public Window
{
public:
MainWindow(const string&);
void draw(const DrawContext&);
};

...

class MySpecialMainWindow : public MainWindow { public:
MySpecialMainWindow(const string& title) :
MainWindow(title)
{
addChildWindow(new ThreeDToolbarWindow);
}
};

void Window::draw(const DrawContext& dc) {
set<Window*>::iterator kid_it = child_windows.begin(); while (kid_it
!= child_windows.end()) {
(*kid_it)->draw(dc);
++kid_it;
}
}
}


Jul 19 '05 #15

P: n/a
On Tue, 22 Jul 2003 16:28:00 -0400, Victor Bazarov wrote:
"Jingz" <e@spam.com> wrote...
[...]
Not to open up another can of worms, but inheritance is probobly my
favorite example of a good idea gone bad. Everyone agree is it can be
over/mis used, but I will contend that it is almost never a good idea.
It obscures functionality at best, at worst is is an absolutely
impenatrable series of tracing back multiple-inheritance spaghetti when
a call goes bad and needs to be debugged. 'has a' is far superior,
necessitating a dereference and obviating that another block of code is
being invoked. "is a" is almost never justified.

I really would like to see you implement polymorphism without
inheritance. Or is polymorphism an overrated "touchy-feely OO" as well?
Would you like to try this discussion in comp.object?

Nobody forces you to use any of the language features. If you think
that 'const' is bogus, don't use it. Inheritance is no good? Live
without it. What I don't understand is the need to "content" the
usability of any feature. Live and let live. Or is the language too
complex for you with all that "spaghetti" in it? Could it be that you
just need to make an effort and simply learn it?

I hope you don't see this as "over/mis used" typing.

Victor


In terms of "the tone I've taken" I have been factual, substantive and
non-confrontational. You on the other hand, seem to want a simple
difference in opinion to be a personal attack against me with fairly rude
and immature innuendo.

-Curt

Jul 19 '05 #16

P: n/a
"Jingz" <e@spam.com> wrote in message
news:pa**********************************@spam.com ...
I know I can't win, you are in quite authoritative company in terms of
people I've argued with about programming paradigms, and I know anyone
reading this agrees with you, not me, but I do feel compelled to stick to
facts.

Microsoft thinks defined like "BOOL" and "WORD" make sense, so I'm not
quite sure invoking problems with their source code is credible.
The Microsoft Windows API is written for C compilers somewhere in the
eighties, they could not use C++ features. The choices they made do not
always make sense from a C++ point of view. Besides that Microsoft does not
always make the best possible technical decisions. Short macro names like
"BOOL" and "WORD" are likely to clash. The reason that they don't clash
that often in reality is that most programmers know that those names are
used in <windows.h>, so they use other names.
I have
indeed never seen a sane define collide in the manner you suggest happens
"all the time" but if we're going to assume insane programmers then you
can prety much claim anything you choose.
What you say may make sense for small projects, but with large complicated
projects the rules change. Problems that might seem accademic in one
context, may become a very real problems in another context. For example if
you use multiple 3rd party libraries or work on a large projects, name
clashes are not all that uncommon. I'm not making this up, I'm speaking from
personal experience. The usual workaround for these problems is using a
prefix for macro names. But what if two 3rd party libraries have name
clashes? In that case you are in deep shit I can tell you. Sure you can
modify the header files. But that means maintaining your own version of that
header file. Every time a new version of the library is released you will
have to do the modifications again. This can become quite a headache, and
therefore one should be extremely reluctant to do so.

Namespaces provide a much more elegant and scalable solution for the name
clash problem than prefixes. However preprocessor symbols don't care about
namespaces. Neither prefixes nor namespaces guarantee that you won't have
name clashes, but they do diminish the change you will get one.
I certainly agree that c++ promotes code cloarity and maintainability, no
question about it, but te fact that it can is often used as a cudgel to
beat code with. Complicated multiple inheritance, templates, and bizzare operator overloading are automatically easier to maintain? I think not. They CAN
be, but care must be used, as in all programming.


I absolutely agree with the last sentence. C++ is a very powerful
programming language; in the right hands wonderful things can be done with
it, but in the wrong hands it is more like letting a monkey play with a gun.
In general I think the designers of the C++ made pragmatic decisions. Most
features in the language are there for a (good) reason, even if they don't
seem make all that much sense at first.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Jul 19 '05 #17

P: n/a
On Tue, 22 Jul 2003 17:56:04 -0400, Victor Bazarov wrote:
"Jingz" <e@spam.com> wrote...
[...]
In terms of "the tone I've taken" I have been factual [..]


Which part in your "inheritance obscures functionality at best" tirade
is factual?


A call to someFunct(); that is not found in the implementation/header file of
the class you are on, is either global or (more probobly, in a
well-formed project, an inherited class)

In order to understand that program you must now track down which class
its in, and in the case of multiple inheritance this can become quite
annoying. Of course in a codebase you are very famliar with, or perhaps
one you wrote yourself, this is not a big deal; in a large project or in
maintaining a new set of code it becomes a very big deal. It also, I
believe, fits a reasonable definition of "obscuring".

Consider now the case of m_3dWidget->someFunc(); by making it a 'has a'
reference, you pinpoint exactly where it is.

-Curt

Jul 19 '05 #18

P: n/a


Jingz wrote:

[...]

Thank you for your response.
const int constantA = 10;
static const int constantB = 20;

int main( int argn, char *argv[] )
{
for( volatile int i=0; i<constantA ; i++ ); for( volatile int j=0;
j<constantB ; j++ );

return 0;
}
}

Why are you using volatile for a local variable?


Because the original responders wanted to tell me how smart they were
about proper c++ rather than answer the obvious question in a meaningful
way. So I composed an equally trivial example that would force code
generation.


But that loops still does no work other then consuming CPU time.
An optimizer might drop them.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #19

P: n/a


Jingz wrote:

On Tue, 22 Jul 2003 17:56:04 -0400, Victor Bazarov wrote:
"Jingz" <e@spam.com> wrote...
[...]
In terms of "the tone I've taken" I have been factual [..]


Which part in your "inheritance obscures functionality at best" tirade
is factual?


A call to someFunct(); that is not found in the implementation/header file of
the class you are on, is either global or (more probobly, in a
well-formed project, an inherited class)

In order to understand that program you must now track down which class
its in, and in the case of multiple inheritance this can become quite
annoying. Of course in a codebase you are very famliar with, or perhaps
one you wrote yourself, this is not a big deal; in a large project or in
maintaining a new set of code it becomes a very big deal. It also, I
believe, fits a reasonable definition of "obscuring".


Right. And?
That's why we are professinoals and get paid for it. If every teeny weeny
newbie could do that we wouldn't earn our money. Building a rocket technically
isn't very distinct from buildind a bicycle. You use the same tools. And yet
building a rocket is incredible more complex then building a bike and one
needs to take care of much more things. That's why rocket engineers earn
much more money, they know how to do it and more importantly: they can do it.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #20

P: n/a

"Curt" <cN****@nSoPrthAarMc.com> wrote in message
news:Xn************************@63.223.5.254...
int main( int argn, char *argv[] )
This isn't wrong but I recommend that you stick to the standard argc versus
argn. On the other hand, you're not using any command line arguments passed
in the first place.
{
for( volatile int i=0; i<constantA ; i++ );
for( volatile int j=0; j<constantB ; j++ );

return 0;
}

Jul 19 '05 #21

P: n/a
Karl Heinz Buchegger <kb******@gascad.at> wrote in
news:3F**************@gascad.at:


Jingz wrote:

[...]

Thank you for your response.
>
>> const int constantA = 10;
>> static const int constantB = 20;
>>
>> int main( int argn, char *argv[] )
>> {
>> for( volatile int i=0; i<constantA ; i++ ); for( volatile int
>> j=0; j<constantB ; j++ );
>>
>> return 0;
>> }
>> }
> Why are you using volatile for a local variable?
>


Because the original responders wanted to tell me how smart they were
about proper c++ rather than answer the obvious question in a
meaningful way. So I composed an equally trivial example that would
force code generation.


But that loops still does no work other then consuming CPU time.
An optimizer might drop them.


Correct, but using 'volatile' compels the compiler to encode as written.
The point of the example has nothign to do with how the constantA/B is used
other than the fact that their address is never taken.

-Curt

Jul 19 '05 #22

P: n/a
On Tue, 22 Jul 2003 13:49:30 GMT, Curt <cN****@nSoPrthAarMc.com>
wrote:
If this is the complete program (ie, the address of the const is never
taken, only its value used) is it likely the compiler will allocate ram for
constantA or constantB? Or simply substitute the values in (as would be
required if I used the hideous, evil, much-abused #define :)

-----------

const int constantA = 10;
static const int constantB = 20;
static is superfluous above - namespace scope consts are static by
default. Perhaps you want:

extern const int constantC = 30;

void main()
{
for( int i=0; i<constantA ; i++ );
for( int j=0; j<constantB ; j++ );
}


Even a stupid compiler should manage to avoid allocating any static
storage for the constants, unless they are declared extern, in which
case only compilers with whole program optimization will be able to
eliminate the storage.

Tom
Jul 19 '05 #23

P: n/a
"Fao, Sean" <en**********@yahoo.comI-WANT-NO-SPAM> wrote in
news:hM***************@news.abs.net:

"Curt" <cN****@nSoPrthAarMc.com> wrote in message
news:Xn************************@63.223.5.254...
int main( int argn, char *argv[] )


This isn't wrong but I recommend that you stick to the standard argc
versus argn. On the other hand, you're not using any command line
arguments passed in the first place.


I tend to think of is as "args - number" and "args - values" and have seen
argn and argc (count, I presume) both used.

-Curt

Jul 19 '05 #24

P: n/a
"Curt" <cN****@nSoPrthAarMc.com> wrote...
"Fao, Sean" <en**********@yahoo.comI-WANT-NO-SPAM> wrote in
news:hM***************@news.abs.net:

"Curt" <cN****@nSoPrthAarMc.com> wrote in message
news:Xn************************@63.223.5.254...
int main( int argn, char *argv[] )


This isn't wrong but I recommend that you stick to the standard argc
versus argn. On the other hand, you're not using any command line
arguments passed in the first place.


I tend to think of is as "args - number" and "args - values" and have seen
argn and argc (count, I presume) both used.


It absolutely doesn't matter how you name them. Convention to
name the first argument 'argc' and the second 'argv' is just that,
a convention.

Victor
Jul 19 '05 #25

P: n/a
"Peter van Merkerk" <me*****@deadspam.com> wrote in
news:bf************@ID-133164.news.uni-berlin.de:

Microsoft thinks defined like "BOOL" and "WORD" make sense, so I'm
not quite sure invoking problems with their source code is credible.


The Microsoft Windows API is written for C compilers somewhere in the
eighties, they could not use C++ features. The choices they made do


Yes I remember, they were wrong then and are wrong now, but chose not to
bite the bullet and re-architect when 16-bit os's were basically dead-ended
on the desktop. I said so at the time, but no one listened to me then
either ;)

Having said that, for all the bashing, Microsoft does have some truly
brilliant programmers cranking out code, its too bad it get tainted by the
other things they do.
I have
indeed never seen a sane define collide in the manner you suggest
happens "all the time" but if we're going to assume insane
programmers then you can prety much claim anything you choose.


What you say may make sense for small projects, but with large
complicated projects the rules change. Problems that might seem
accademic in one context, may become a very real problems in another
context. For example if you use multiple 3rd party libraries or work
on a large projects, name clashes are not all that uncommon. I'm not
making this up, I'm speaking from personal experience. The usual
workaround for these problems is using a prefix for macro names. But
what if two 3rd party libraries have name clashes? In that case you
are in deep shit I can tell you. Sure you can modify the header files.
But that means maintaining your own version of that header file. Every
time a new version of the library is released you will have to do the
modifications again. This can become quite a headache, and therefore
one should be extremely reluctant to do so.


Having worked on both, I think you are overgeneralizing. A large project
that has those kinds of collisions is mismanaged and has other problems.
However working with 3rd party libraries I can believe it. I have had some
experience with graphics and XML libraries in this regard, and almost
always wrap that functionality using our established coding standards. I
would be curious to see an example where such a wrapper would not solve the
name collision.

-Curt

Jul 19 '05 #26

P: n/a
Karl Heinz Buchegger <kb******@gascad.at> wrote in
news:3F***************@gascad.at:


Jingz wrote:

On Tue, 22 Jul 2003 17:56:04 -0400, Victor Bazarov wrote:
> "Jingz" <e@spam.com> wrote...
>> [...]
>> In terms of "the tone I've taken" I have been factual [..]
>
> Which part in your "inheritance obscures functionality at best"
> tirade is factual?
>


A call to someFunct(); that is not found in the implementation/header
file of the class you are on, is either global or (more probobly, in
a well-formed project, an inherited class)

In order to understand that program you must now track down which
class its in, and in the case of multiple inheritance this can become
quite annoying. Of course in a codebase you are very famliar with, or
perhaps one you wrote yourself, this is not a big deal; in a large
project or in maintaining a new set of code it becomes a very big
deal. It also, I believe, fits a reasonable definition of
"obscuring".


Right. And?
That's why we are professinoals and get paid for it. If every teeny
weeny newbie could do that we wouldn't earn our money. Building a
rocket technically isn't very distinct from buildind a bicycle. You
use the same tools. And yet building a rocket is incredible more
complex then building a bike and one needs to take care of much more
things. That's why rocket engineers earn much more money, they know
how to do it and more importantly: they can do it.


I do agree that professionals get payed to do the job they are experts
in. Now please do not take this as personal criticism, but I firmly
believe in dumbing everything down as much as possible, so the brain-
cycles can be spent on the really difficult problems. Put too simply- if
its tedious and difficult to cut and paste text, then thats less effort
and time you can spend concentrating on the content of that text.

I prefer structures to be simple and straightforward, so the task they
are performing becomes the focus.

I will be the first to admit this may be the result of the type of work I
do, which is enormous, high-bandwidth databases, bare-metal embedded
work, and gui interfaces to them. In deference to that, I am always
looking to learn new things and not a day goes by that I don't learn
something interesting about the programming art. Its wonderful being part
of such a bottomless industry, in terms of knowledge and new experiences.

-Curt

Jul 19 '05 #27

P: n/a

"Curt" <cN****@nSoPrthAarMc.com> wrote in message news:Xn************************@63.223.5.254...
I should have mentioned this in the original post, but the application is
that the const is being defined in a header file that is included in many
translation units, and I want to make sure a new copy is not created for
each time it is used (as would be the case using a #define) but prefer to
use the namespace/typsafety of 'const int'.


Even in header files, consts at namespace scope are static.
Jul 19 '05 #28

P: n/a
On Wed, 23 Jul 2003 18:21:28 GMT, Curt <cN****@nSoPrthAarMc.com>
wrote:
const int constantA = 10;
static const int constantB = 20;


static is superfluous above - namespace scope consts are static by
default. Perhaps you want:

extern const int constantC = 30;


Thank you for your response.

I should have mentioned this in the original post, but the application is
that the const is being defined in a header file that is included in many
translation units, and I want to make sure a new copy is not created for
each time it is used (as would be the case using a #define) but prefer to
use the namespace/typsafety of 'const int'.


In a header it is still static - each translation unit sees a
"different" const variable (that happens to have the same name and
value) and each translation unit can be considered separately. The
advantage of static is that the compiler doesn't have to work out that
you aren't taking the address of the const in any translation unit,
but only in the current translation unit.

Finally, one thing to be aware of is that some compilers may allocate
storage for a const if you pass it by reference in that translation
unit (to a non-inline function perhaps?) in addition to if you take
its address.

Tom
Jul 19 '05 #29

P: n/a


Karl Heinz Buchegger wrote:

???
There seems to be a misconception of what volatile really does.
In the above, volatile doesn't do, what you seem to think it does.


Apologies.
It was my fault. A few seconds after hitting 'send', I realized what you
are aming at. And it will work. You are right and I was wrong.

One more time: Apologies.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 19 '05 #30

P: n/a

Karl Heinz Buchegger wrote:

Karl Heinz Buchegger wrote:

???
There seems to be a misconception of what volatile really does.
In the above, volatile doesn't do, what you seem to think it does.


Apologies.
It was my fault. A few seconds after hitting 'send', I realized what you
are aming at. And it will work. You are right and I was wrong.

One more time: Apologies.


Sorry, but volatile *indeed* doesn't do what you seem to think it
does. Nobody knows what it does because it's totally brain-damaged
"concept".

So, you're wrong and I'm right, of course.

regards,
alexander.
Jul 19 '05 #31

P: n/a
On Thu, 24 Jul 2003 10:35:40 -0400, Alexander Terekhov wrote:

Karl Heinz Buchegger wrote:
Apologies.
It was my fault. A few seconds after hitting 'send', I realized what
you are aming at. And it will work. You are right and I was wrong.

No problemo, wasn't going to say anything ;)

Sorry, but volatile *indeed* doesn't do what you seem to think it does.
Nobody knows what it does because it's totally brain-damaged "concept".

So, you're wrong and I'm right, of course.

regards,
alexander.


I've bever used it myself, and without looking it up in the ARM or google
or anything, I seem to recall volitile being used to keep the compiler
from optimizing out necessary code that looks harmless, a simple example
might be a (poorly written) multithreaded program:

void thread1()
{
int i;
invokethread( thread2, &i );

i = 1;

sleep( 100 );

while( i == 2 );

..
..
..
}

void *thread2( void *arg )
{
int *p = (int *)arg;

*p = 2;

return 0;
}

--------

In this example, admittedly braindead, a clever compiler might look at
thread1 and see that a locally-scoped 'i' could not be modified by
'sleep', and the next check "while" will never succeed, and it might be
optimized out. by declaring 'i' as volatile, the compiler must honor all
references to its value.

This actally has applications in interrupt-driven device drivers, as I
say I've never had a need for it, and I could be wrong! Its been some
years since I looked up its function.

-Curt

Jul 19 '05 #32

P: n/a
"Jingz" <e@spam.com> wrote in message
news:pa*********************************@spam.com. ..
On Thu, 24 Jul 2003 10:35:40 -0400, Alexander Terekhov wrote:
Sorry, but volatile *indeed* doesn't do what you seem to think it does. Nobody knows what it does because it's totally brain-damaged "concept".
So, you're wrong and I'm right, of course.

regards,
alexander.
I've bever used it myself, and without looking it up in the ARM or

google or anything, I seem to recall volitile being used to keep the compiler
from optimizing out necessary code that looks harmless, a simple example might be a (poorly written) multithreaded program:


The C++ standard doesn't care about multi-threading. Making variables
volatile will not guarantee correct behaviour in a multi-threaded
environment. Unless you know exactly what your compiler does with the
volatile specification and what that means for the execution
environment, the volitile keyword is of little or no use in most cases.

Non volatile variables may loaded at (more or less) arbitratrary times
from memory into a processor register and written back to memory at
(more or less) arbitrary times as well, in the meanwhile the value of
the value may have been changed many times without those changes being
reflected in memory. This optimization is problematic when multiple
threads access the same variable, as they essentially may operate on
their copy of the variable and don't see the changes made by the other
threads. Usually declaring a variable volatile means that the value of a
variable is loaded from memory every time it is needed, and written back
to memory every time its value is changed. However this doesn't
guarantee correct behaviour in a multi-threaded enviroment.

Example:

volatile int v=0;

void ThreadA()
{
for(int i = 0; i < 1000; ++i)
{
++v;
}
}

void ThreadB()
{
for(int i = 0; i < 1000; ++i)
{
++v;
}
}

So the question is what will be the value of 'v' when threads A and B
have completed? The answer is that the value of 'v' can be anything
between 1000 and 2000. This is because the line ++v may very well be
translated to three processor instructions:

mov ecx, [v];// Load value from memory into ecx register.
inc ecx // Increment value of ecx register
mov [v], ecx // Write value back to memory.

The problem is that a thread context switch can occure after every
processor instruction. If thread A loads the value 0 from memory into
ecx, and immediately after that instruction a context switch to thread B
occures thread B will read a 0 value for v as well. Now lets suppose
thread B can complete without a context switches to thread A. In that
case the value of variable v in memory will be 1000 at that point in
time. However when thread A continues it will still have 0 in its ecx
register, and after the first iteration of the loop in thread A the
value of v in memory will go back from 1000 to 1. Consequently when
thread A finishes the value of 'v' will be 1000. This is just one
example what may go wrong.

Moral of this story; for proper thread synchronisation you will have to
rely on the facilities offered by the platform, C++ cannot help you
here.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl

Jul 19 '05 #33

P: n/a

Jingz wrote:
[...]
I've bever used it myself, and without looking it up in the ARM or google
or anything, I seem to recall volitile being used to keep the compiler
from optimizing out necessary code that looks harmless, a simple example
might be a (poorly written) multithreaded program: ....


Heck. Advice: *PLONK* volatiles.

http://groups.google.com/groups?selm...1602E%40web.de
(Subject: Re: Volatile and threads.)

http://groups.google.com/groups?selm...5F41B%40web.de
(Subject: Re: Does anyone think 'volatile' is a platform-independent
way to make variable access thread safe?)

regards,
alexander.
Jul 19 '05 #34

P: n/a
> The C++ standard doesn't care about multi-threading. Making variables
volatile will not guarantee correct behaviour in a multi-threaded
environment. Unless you know exactly what your compiler does with the
Reading some of the other posts here I can understand why you jumped to
the conclusion that I don't know the difference between the language and
the system upon which it runs, I think you missed the point of my example.

More plainly, my point was that the 'volatile' qualifier prevents the
compiler from removing references to code that appear to have no effect,
specifically, I presented an example where the address of that variable
was known to another thread of execution.

Precicely because c++ has no concern for threads of execution, interrupt
handlers, pre-emption or any other such higher-level concepts, it must be
told- "no, I really mean check a variable multiple times even though no
code appears to change it between checks, I know better"

Your point about variables being loaded into registers at random times is
well taken, a compiler can decide to sample the value once from main RAM,
then stick it in a register and continue to test it there, I would presume
the 'volatile' qualifier would also prevent this behavior.

Moral of this story; for proper thread synchronisation you will have to
rely on the facilities offered by the platform, C++ cannot help you
here.


Absolutely, and thank you for pointing it out so clearly to anyone else
following this thread who might have also mis-interpreted my example.

-Curt

Jul 19 '05 #35

P: n/a
"Jingz" <e@spam.com> wrote in message
news:pa*********************************@spam.com. ..
The C++ standard doesn't care about multi-threading. Making variables
volatile will not guarantee correct behaviour in a multi-threaded
environment. Unless you know exactly what your compiler does with the
Reading some of the other posts here I can understand why you jumped to
the conclusion that I don't know the difference between the language and
the system upon which it runs, I think you missed the point of my example.


Don't worry, I didn't make any assumptions about your knowledge, and I did
see the point of you example (the point was clear enough even for me to see
it).

The reason I responded is that your posting seemed to confirm a popular
misconception that 'volatile' qualifier would help to solve at least some
multithreading issues. It does not, period. It only gives people a false
sense of security. Misconceptions like this can lead to extremely difficult
to track down bugs. Good luck finding a unreproducable bug that shows its
ugly face about 10 times a year at totally arbitrary times!

I have written plenty of multi-threaded code, but never had any use for the
'volatile' keyword.
The 'volatile' qualifier may have its uses in very particular cases, but
that depends entirely on the platform and the compiler.
More plainly, my point was that the 'volatile' qualifier prevents the
compiler from removing references to code that appear to have no effect,
specifically, I presented an example where the address of that variable
was known to another thread of execution.

Precicely because c++ has no concern for threads of execution, interrupt
handlers, pre-emption or any other such higher-level concepts, it must be
told- "no, I really mean check a variable multiple times even though no
code appears to change it between checks, I know better"

Your point about variables being loaded into registers at random times is
well taken, a compiler can decide to sample the value once from main RAM,
then stick it in a register and continue to test it there, I would presume
the 'volatile' qualifier would also prevent this behavior.


Yes, it does force the compiler to access memory for that variable whenever
it is used or changed. But that still doesn't guarantee correct behaviour in
a multi-threaded environment. Note that the example I provided used a
volatile variable to communicate between two threads, and even in that case
it is not guaranteed it produces the correct result. Many processors cannot
directly manipulate values in memory and have to use registers to do the
actual arithmetic. So even manipulating volatile variables will typically
require several instructions to load, modify and store the variable value.
Consequently modifying a volatile variable cannot be considered to be atomic
operation, hence the 'volatile' qualifier does not guarantee correct
behaviour in a multi-threaded environment.

The funny thing with my example is that if it is compiled with an optimizing
compiler but without the 'volatile' qualifier for variable 'v', the chance
of getting the expected result might actually be higher. If 'v' isn't
volatile the compiler may replace the for loop with 'v+=1000;', which is
much less likely to be interrupted by a context switch.

--
Peter van Merkerk
peter.van.merkerk(at)dse.nl
Jul 19 '05 #36

P: n/a

Peter van Merkerk wrote:
[...]
The funny thing with my example is that if it is compiled with an optimizing
compiler but without the 'volatile' qualifier for variable 'v', the chance
of getting the expected result might actually be higher. If 'v' isn't
volatile the compiler may replace the for loop with 'v+=1000;', which is
much less likely to be interrupted by a context switch.


Compiler *may* replace the for loop with 'v+=1000;' even if v is
volatile. You still don't get it, I'm afraid.

regards,
alexander.
Jul 19 '05 #37

P: n/a

Peter van Merkerk wrote:
[...]
Though it doesn't prove anything, on all compilers I ever tried, the
volatile keyword does actually affect the generated code, but not in a way
it is of any use in a multi-threaded environment. If you are right, I wonder
why compilers bother doing something with the 'volatile' keyword instead of
treating it the same way they typically do with the 'register' keyword, i.e.
ignore it.


Well, in this case, the reason is nothing but "stupidity rules", I
think. As I said, volatile is totally brain-damaged.

http://groups.google.com/groups?thre...1D2D6%40web.de
http://groups.google.com/groups?selm...1602E%40web.de

regards,
alexander.
Jul 19 '05 #38

This discussion thread is closed

Replies have been disabled for this discussion.