Self-overwriting class - is 'volatile' needed for field keepers?

O

Ole Nielsby

I have objects that sometimes overwrite themselves by something else,
using placement new.

I will spare you for the details, but the objects serve as stack frames
and are placed contiguosly, and the overwriting happens when a frame
gets popped and something else gets pushed. This is a much simplified
version:

class Frame {...}

class Frame1 : Frame {...}

class Frame2 : Frame {
private:
int /*volatile?*/ f;
public:
void m() {
int ff = f;
new ((void*)this) Frame1(...);
doSomething(ff);
}
}

This seems to work so far. What bugs me is: could a smart
optimizer decide that f can't be modified because it is private
and no Frame2 methods modify it, and then postpone the
fetching until after the placement new? Is the volatile
keyword sufficient/required to prevent this? If I don't want
to make all such fields volatile (since this may prevent some
valid optimizations), can I achieve the same effect by:

int ff = *((int *volatile)&f);

or whatever the syntax? Or:

int volatile ff = f;

Or should I expose dummy methods that modify the fields?

class Frame2 ...{... void dummy(){f = 0;} ....}
 
G

Gianni Mariani

Ole said:
I have objects that sometimes overwrite themselves by something else,
using placement new.

I will spare you for the details, but the objects serve as stack frames
and are placed contiguosly, and the overwriting happens when a frame
gets popped and something else gets pushed. This is a much simplified
version:

class Frame {...}

class Frame1 : Frame {...}

class Frame2 : Frame {
private:
int /*volatile?*/ f;

Volatile is only needed to tell the compiler not to cache the value.
i.e. when the program references the value, it should be read from that
location. However, this only happens in very special circumstances,
e.g. multi threaded programs, system interrupts, signals, devices etc.
public:
void m() {
int ff = f;
new ((void*)this) Frame1(...);
doSomething(ff);
}
}

This seems to work so far. What bugs me is: could a smart
optimizer decide that f can't be modified because it is private
and no Frame2 methods modify it, and then postpone the
fetching until after the placement new?

A compiler would be wrong to assume that so you're probably safe without it.
....

It seems like you're doing somthing pretty crazy anyway so you're
probably doing somthing that is implementation dependant.
 
T

tomthemighty

This seems to work so far. What bugs me is: could a smart
optimizer decide that f can't be modified because it is private

No, only a dumb one.

volatile indicates that the variable might change for reasons
undetectable to the compiler. It is implementation-defined what that
means, but it is intended to cover writes from outside the program at
run-time (eg memory-mapped hardware registers). It is not intended to
cover situations where the compiler's left hand doesn't know what its
right hand is doing.

If your placement new call causes f to change, then it will be
compiler-generated code that makes the change. As long as your code is
standard-compliant (a big if, considering what you are doing), then it
is up to the compiler to ensure that it generates object code that does
what it should.

I thought you had undefined behaviour because you aren't calling the
destructor of the object you are replacing, but 3.8 para 4 in the
standard indicates that is ok.
 
O

Ole Nielsby

Gianni Mariani said:
Ole said:
I have objects that sometimes overwrite themselves by something else,
using placement new.

A compiler would be wrong to assume that [private fields won't change]
so you're probably safe without it.

I take your word and feel probably safe.
It seems like you're doing somthing pretty crazy anyway so you're probably
doing somthing that is implementation dependant.

C++ wasn't meant for writing fast interpreters for functional languages
using vtable-based stack frames... so I have to bend it a bit and hope
it doesn't break. Anyway, I understand from the answers that 'volatile'
is not for this kind of situation.

Regards/Ole Nielsby
 

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