0

I want to verify the role of volatile by this method. But my inline assembly code doesn't seem to be able to modify the value of i without the compiler knowing. According to the articles I read, I only need to write assembly code like __asm { mov dword ptr [ebp-4], 20h }, I think I write the same as what he did.

actual output:

before = 10
after = 123

expected output:

before = 10
after = 10

Article link: https://www.runoob.com/w3cnote/c-volatile-keyword.html

#include <stdio.h>

int main() {
    int a, b;
    // volatile int i = 10;
    int i = 10;

    a = i;
    printf("before = %d\n", a);

    // Change the value of i in memory without letting the compiler know.
    // I can't run the following statement here, so I wrote one myself
    // mov dword ptr [ebp-4], 20h
    asm("movl $123, -12(%rbp)");

    b = i;
    printf("after = %d\n", b);
}
qingl
  • 71
  • 7

1 Answers1

1

I want to verify the role of volatile ...

You can't.

If a variable is not volatile, the compiler may optimize; it does not need to do this.

A compiler may always treat any variable as volatile.

How to change the value of a variable without the compiler knowing?

Create a second thread writing to the variable.

Example

The following example is for Linux (under Windows, you need a different function than pthread_create()):

#include <stdio.h>
#include <pthread.h>

int testVar;
volatile int waitVar;

void * otherThread(void * dummy)
{
    while(waitVar != 2) { /* Wait */ }
    testVar = 123;
    waitVar = 3;
    return NULL;
}

int main()
{
    pthread_t pt;
    waitVar = 1;
    pthread_create(&pt, 0, otherThread, NULL);
    testVar = 10;
    waitVar = 2;
    while(waitVar != 3) { /* Wait */ }
    printf("%d\n", testVar - 10);
    return 0;
}

If you compile with gcc -O0 -o x x.c -lpthread, the compiler does not optimize and works like all variables are volatile. printf() prints 113.

If you compile with -O3 instead of -O0, printf() prints 0.

If you replace int testVar by volatile int testVar, printf() always prints 113 (independent of -O0/-O3).

(Tested with the GCC 9.4.0 compiler.)

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • *If you replace `int testVar` by `volatile int testVar`, `printf()` always prints 113 (independent of `-O0`/`-O3`).* That is not guaranteed to happen. See [**Why is volatile not considered useful in multithreaded C or C++ programming?**](https://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming). Also see [Hans Boehm's description of just what `volatile` means](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2016.html). For one, it doesn't mean "atomic". – Andrew Henle Apr 02 '22 at 10:45
  • @AndrewHenle You are right. Theoretically, the threads may access different CPU caches... – Martin Rosenau Apr 02 '22 at 11:07