Search code examples
c++chardwarevolatile

Is is necessary to use volatile when writing to hardware in C or C++?


Is it necessary to use volatile when writing to hardware (say a FIFO) in C or C++. It is easy to confirm from online documentation that volatile is necessary when reading hardware, but what about writing? I am concerned that an optimiser could eliminate a loop to write an array of values to a FIFO, and just write the last entry.


Solution

  • Just try it.

    #define MYFIFOV (*((volatile unsigned char *)0x1000000))
    #define MYFIFO (*((unsigned char *)0x1000000))
    
    void funv ( void )
    {
        MYFIFOV=0;
        MYFIFOV=0;
    }
    void fun ( void )
    {
        MYFIFO=0;
        MYFIFO=0;
    }
    00000000 <funv>:
       0:   e3a03401    mov r3, #16777216   ; 0x1000000
       4:   e3a02000    mov r2, #0
       8:   e5c32000    strb    r2, [r3]
       c:   e5c32000    strb    r2, [r3]
      10:   e12fff1e    bx  lr
    
    00000014 <fun>:
      14:   e3a03401    mov r3, #16777216   ; 0x1000000
      18:   e3a02000    mov r2, #0
      1c:   e5c32000    strb    r2, [r3]
      20:   e12fff1e    bx  lr
    

    strb means store byte. Without the volatile one of the writes was optimized out. So yes without volatile, writes can be optimized out. How and when the compiler decides to do it can vary. But assume it can happen and as a result cause you problems.