Does this allocate memory?

F

Fao, Sean

Curt said:
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.
 
C

Curt

[...]

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
 
T

tom_usenet

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 :)

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
 
C

Curt

Curt said:
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
 
V

Victor Bazarov

Curt said:
Curt said:
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
 
C

Curt

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.
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
 
C

Curt

[...]
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
 
R

Ron Natalie

Curt said:
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.
 
T

tom_usenet

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
 
K

Karl Heinz Buchegger

Karl said:
???
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.
 
A

Alexander Terekhov

Karl said:
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.
 
J

Jingz

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
 
P

Peter van Merkerk

Jingz said:
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.
 
A

Alexander Terekhov

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/[email protected]
(Subject: Re: Volatile and threads.)

http://groups.google.com/[email protected]
(Subject: Re: Does anyone think 'volatile' is a platform-independent
way to make variable access thread safe?)

regards,
alexander.
 
J

Jingz

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
 
P

Peter van Merkerk

Jingz said:
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.
 
A

Alexander Terekhov

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.
 
A

Alexander Terekhov

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/[email protected]
http://groups.google.com/[email protected]

regards,
alexander.
 

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,057
Latest member
KetoBeezACVGummies

Latest Threads

Top