2

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?

Theo d'Or
  • 783
  • 1
  • 4
  • 17
  • 1
    Compilers do some analysis to determine things like this, but a complete solution is not possible. It is equivalent to the Halting Problem: If we could write software that determined whether particular code flow with particular inputs did not modify a particular object, then we could write software that modified a particular object only if the previous software, called as a subroutine, said this software did not modify the object. – Eric Postpischil Sep 26 '20 at 16:30
  • Please elaborate a bit: What is the difference you expect, let's say, on a low level like assembly? Or do you expect that such a variable (if it is static) will be placed in `.rodata` instaed of `.data`? – the busybee Sep 26 '20 at 16:34
  • @thebusybee I would expect it to work similar to how `const` works. I don't know the low level details of that apart from the possibility of the variable being read-only, presumably with faster access being possible. In my research I did come across some discussions about where the data would be stored, so your idea of `.rodata` vs `.data` might indeed be part of it. – Theo d'Or Sep 26 '20 at 22:26

1 Answers1

5

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.

  • does this basic idea apply to const char pointers (and other const pointers) as well ? – A P Jo Sep 26 '20 at 16:45
  • You mean pointers to const char? It is not the pointer that is const, only the pointed-to element. But YMMV, again. – Antti Haapala -- Слава Україні Sep 26 '20 at 16:55
  • Thank you for this interesting answer. I would assume that if the compiler considers the unchanging value for loop unrolling then it also considers it for read-only access, that is faster memory access than regular read-write RAM. I'm mindful of the old wisdom "never assume" though, so would still appreciate an answer addressing the read-only access specifically. – Theo d'Or Sep 26 '20 at 22:31
  • There is no "faster readonly memory" in general computing nowadays, what would you be referring to? – Antti Haapala -- Слава Україні Sep 26 '20 at 22:35
  • @AnttiHaapala It appears that I (as well as some participants in discussions I've read) have misunderstood the statement in the K&R2 book p. 211: "const is to announce objects that may be placed in read-only memory, and perhaps to increase opportunities for optimization". I understood read-only access itself to be an optimization, but is it? Is the optimization that the book refers to only of the kind that you demonstrated, like loop unrolling? But then, if read-only access is not faster, what's the point of it? – Theo d'Or Sep 27 '20 at 11:26
  • There are space and runtime memory savings that are possible too. But the speed optimization aspect is not about speed of memory though but understanding that a constant is... a constant – Antti Haapala -- Слава Україні Sep 27 '20 at 12:53