Are C optimizing compilers (GCC) able to detect unchanging values for read-only access without the use of 'const'?

150 views Asked by At

My searches have turned up blank on this question... There are plenty of discussions of how const may be helpful in compiler optimization by signaling read-only access of a variable, but I can't find an answer to the question as posed in the title. I'm interested in the question because I want to avoid thinking about using const for optimization if the compiler can do that anyway.

I appreciate that even if the compiler is able to find unchanging values and optimize them to read-only access, there will be cases where use of const would still be helpful. I'm just looking for an answer on compiler capability in broad terms - does the GCC optimizer look for unchanging values without the use of const?

1

There are 1 answers

6
Antti Haapala -- Слава Україні On BEST ANSWER

My GCC, with -O3 compiles the following code

#include <stdio.h>

static int count1 = 3;
int count2 = 3;
const int count3 = 3;

int main(void) {
    for (int i = 0; i < count; i++) {
        printf("Hello world\n");
    }

    for (int i = 0; i < count2; i++) {
        printf("Hello again\n");
    }

    for (int i = 0; i < count3; i++) {
        printf("Hello once more\n");
    }
}

to equivalent of

#include <stdio.h>

int count2 = 3;
const int count3 = 3;

int main(void) {
    puts("Hello world");
    puts("Hello world");
    puts("Hello world");
   
    for (int i = 0; i < count2; i++) {
        puts("Hello again");
    }

    puts("Hello once more");
    puts("Hello once more");
    puts("Hello once more");
}

Clearly the first loop was unrolled even without const-qualified count1, because it has internal linkage.

count2 has external linkage, and it will be impossible for the compiler to prove that some other translation unit that you link with this translation unit would not modify the static variable in some constructor function before main was executed and the optimization would be disabled.

count3 is const-qualified. The compiler knows that no other translation unit can change its value either and the loop will be unrolled, despite count3 having external linkage, and the same variable being visible to other translation units.