Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meaning of volatile for arrays and typecasts

Folks,

Consider this (abominable) piece of code:

volatile unsigned long a[1];  
unsigned long T; 

void main(void) 
{    
    a[0] = 0x6675636b;   /* first access of a */
    T = *a; 
    *(((char *)a) + 3) = 0x64; /* second access of a */
    T = *a;
}

...the question: is ((char *)a) volatile or non-volatile?

This begs a larger question: should there be a dependence between the two accesses of a? That is, human common sense says there is, but the C99 standard says that volatile things don't alias non-volatile things -- so if ((char *)a) is non-volatile, then the two accesses don't alias, and there isn't a dependence.

More correctly, C99 6.7.3 (para 5) reads:

"If an attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type, the behavior is undefined."

So when we typecast a, does the volatile qualifier apply?

like image 384
user1794790 Avatar asked Nov 02 '12 16:11

user1794790


1 Answers

When in doubt, run some code :) I whipped up some similar (slightly less abominable) test code (win32 C++ app in msvs 2k10)

int _tmain(int argc, _TCHAR* argv[]) {
    int a = 0;
    volatile int b = 0;

    a = 1; //breakpoint 1
    b = 2; //breakpoint 2
    *(int *) &b  = 0; //breakpoint 3
    *(volatile int *) &b  = 0; //breakpoint 4

    return 0;
}

When compiled for release, I am allowed to breakpoint at 2 and 4, but not 1 and 3.

My conclusion is that the typecast determines the behavior and 1 and 3 were optimized away. Intuition supports this - otherwise compiler would have to keep some type of list of all locations of memory listed as volatile and check on every access (hard, ugly), rather than just associating it with the type of the identifier (easier and more intuitive).

I also suspect it's compiler specific (and possibly flag specific even within a compiler) and would test on any platform before depending on this behavior.

Actually scratch that, I would simply try to not depend on this behavior :)

Also, I know you were asking specifically about arrays, but I doubt that makes a difference. You can easily whip up similar test code for arrays.

like image 68
davec Avatar answered Oct 29 '22 09:10

davec