Search code examples
c

Will C Compiler Optimize Dereferencing in Loop?


Imagine I have this structure:

struct GayClub { 
  ...
  int ndrinks;
  ...
}

And now I'm looping over like that:

// my struct
struct GayClub gc;

//....

// my loop
int i = 0;
for (; i < gc.ndrinks; ) {
  ...
  // no modifications on gc.ndrinks
  ...
  i++;
}

The questions is will C compiler like GCC or cLang or rustc optimize it like this? This is faster becos I am not de-referencing memory.

// trick
int tmpNDrinks = gc.ndrinks;
// my za-loop-a
for (; i < tmpNDrinks; ) {
  ...
  // no modifications on gc.ndrinks
  ...
  i++;
}

Again, I am asking this becos I do NOT want to extract limits to a separate variable every time if compiler already does that for me.


Solution

  • This depends on multiple factors, including:

    • Whether it is a good compiler.

    • Whether you have enabled optimization in the compiler.

    • Whether it is visible to the compiler that the object will not be modified by other means.

    For example, suppose the body of the loop uses some int *p that is passed as a parameter or is loaded from a data structure. If the body of the loop contains *p, how can the compiler know whether p points to gc.ndrinks or not? If the compiler cannot know, as a mathematical proof, that p does not point to gc.ndrinks, then it must generate code as if p could point to gc.ndrinks.

    Your example is incomplete, so it is not clear to the reader whether gc is defined inside a function and has automatic storage duration. If it does, then the compiler may presume no parameter points into gc, because gc did not exist at the time the function was called. However, if int *p is something other than a parameter, or if gc is defined outside a function, the compiler may not be able to determine that p cannot point to gc.ndrinks.

    Quite often, if you wish to be sure a value is cached throughout a loop, you should create a variable to hold that value. It is cheap, as the burden of tracking the variable’s value falls to the compiler, which will optimize its use. Which is the point.