The volatile Keyword

Perhaps the most hilarious keyword in the C language is volatile. It’s a data type qualifier, which I discussed in last week’s Lesson. But this qualifier doesn’t mean that the data is unstable or risky to use, unlike other things described as “volatile.”

Like the other C language type qualifiers — const, restrict, and _Atomicvolatile has more to do with the compiler optimizing code than with anything that happens to data once a program is running.

The direction that volatile gives to the compiler is that the data shouldn’t be optimized at all, ever. I mention this specific use in a post from a year ago where I recommended using the volatile keyword to prevent the compiler from optimizing a routine to zero-out memory.

2022_01_14-Lesson.c

#include <stdio.h>

void memzero(void *b, int len)
{
    volatile int x;
    char *a;

    a = (char *)b;
    for( x=0; x<len; x++)
        *(a+x) = 0;
}

int main()
{
    struct human {
        char name[32];
        int age;
        float weight;
    } my;

    memzero(&my,sizeof(struct human));

    return(0);
}

The memzero() function is a re-write of the memset() function in C, which is considered non-secure: If you want to zero a buffer to erase sensitive information, memset() might not do the complete job. The compiler can optimize the function’s guts, in which case memory remains untouched.

In the code above, the memzero() function uses the volatile qualifier to ensure that the compiler doesn’t optimize int variable x. Its value isn’t altered as it loops from zero to len, filling buffer b with zero values.

Of course, you can replace the memset() function with memset_s() to avoid optimization; you need not write your own function, but the memzero() function does demonstrate a valid use for the volatile qualifier. (The upcoming C23 standard includes the memset_explicit() function that uses the original memset() function’s arguments, but also guarantees no optimization.)

The final data qualifier in the list is _Atomic, a keyword introduced with the C11 standard (like a few of the other underscore prefix keywords). This keyword creates an atomic data type that can be accessed by multiple threads in a single program.

I cover threaded programming in another post, but not at a level deep enough to discuss how atomic data is used or beneficial. Someday I may further explore this qualifier, but for know just nod knowingly when someone discusses it and say something pithy like, “Certainly atomic qualifiers ease data manipulation for multithreaded activities.” Then quickly change the topic to sports.

2 thoughts on “The volatile Keyword

  1. While it isnʼt the case that I havenʼt found at least some uses for atomic operations – like __sync_add_and_fetch() or, on Windows, InterlockedIncrement() – over the years, I agree with the last part:

    Topics like _Atomic variables and C/C++ʼs memory model are fascinating as well as important, but Iʼve long since resigned myself to the fact that their uses – implementing mutexes, atomic operations and especially lock-free programming – should probably be reserved for people who are significantly more intelligent than I am.

    That being said: after the release of C++11, Microsoftʼs Herb Sutter gave a talk titled “atomic Weapons – The C++ Memory Model and Modern Hardware” that, among others, discusses SC-DRF (C/C++ʼs memory model) and can, I think, still be considered a good introduction to the topic.

  2. The topic still frightens me, though I’m happy to know that greater minds understand its usefulness and put it to good work.

Leave a Reply