Can an indirect change to const volatility be considered undefined behavior?
This behavior is undefined (for both operators) when trying to change the "initial" const
object. From C11 (N1570) 6.7.3 / p6 Typical classifiers (emphasis):
If an attempt is made to modify an object defined with a const-qual type using an lvalue with a non-const-qualified type , the behavior is undefined.
For the sake of completeness, it may be added that the Standard also states that:
If an attempt is made to access an object defined with a volatile-qualified type using an lvalue with a non-volatile type , the behavior is undefined.
Hence the last statement, that is:
*(int *)p = 16;
- undefined for the second phrase (this is "double UB").
I believe the rules are the same for C ++, but don't have a copy of C ++ 14 to confirm.
source to share
Writing to a variable is initially const
undefined behavior, so all your examples are written to *p
: undefined.
Deletion volatile
by itself is not undefined in and of itself.
However, if we have something like const volatile int *p = (const volatile int*)0x12340000; /* Address of hw register */
that, then deleting volatile
may cause the hardware to update the register value, but your program won't pick it up. (For example, if we "wait" with while(*p & 0x01) ;
, the compiler must reload the value it points to p
every time, but the while((*(const int *)p) & 1) ;
compiler is completely free to read the values ββand reuses the initial value for the loop forever if bit 0 is set).
You could, of course, have [Edit, no, disabling extern volatie int x;
and then use const volatile int *p = &x;
in some code, and x
updated with some other code outside of your current translation unit (like another thread) - in which case deletion is const
either volatile
valid, but as stated above, you can "skip" updated values ββbecause the compiler does not expect the global value to update outside of your module unless you call functions.volatile
by casting a value is also prohibited in the standard - however, you really need to add const
or volatile
to something and then remove it again if it refers to the original object to not have it].
Edti2: volatile
you need to tell the compiler that "the value can change at any time, even if you think nothing should have changed it." This happens, in general, in two situations:
- Hardware registers that are updated outside of software in general - for example, status registers for a serial port, a timer counter register, or an interrupt controller interrupt state to name a few cases - there are thousands of other options, but it's still the same idea: the hardware changes the value , without direct relation to the software that accesses such registers.
- The variable is updated by another thread in the process (or, in the case of shared memory, by another process) - again, the compiler will not be able to "see" such changes. It is often possible to write code that appears to function correctly, by calling a function inside wait loops, etc., and the compiler will still reload the values ββof non-local variables, but after a while the compiler decides to inline the function call and then realizes that the code is not updating it is a value, so it does not reload the value β error when you check for an "updated" value and find the same old value that was previously loaded by the compiler.
Note also that it is volatile
NOT a guarantee for any thread / process correctness - it just ensures that the compiler does not skip reading or writing to this variable. The programmer doesn't care to make sure, for example, that multiple ordering-dependent values ββare indeed updated in the correct order, and on systems where caches are not consistent between processing units, that caches become coherent by software [for example, processor and the GPU might not use coherent memory updates, so writes by the CPU don't make it to the GPU until the cache is cleared from the CPU - no amount of applying volatile
to code will fix this]
source to share