Does the comp-correctness match the compiler more options for optimization?

I know that it improves readability and makes the program less error prone, but how much does it improve performance?

And on the side of the note, what is the main difference between a link and a const pointer? I would suggest that they are stored in memory in different ways, but how is it?

Thank.

+71
c ++ c pointers const
Jun 11 2018-11-11T00:
source share
7 answers

[Edit: OK, so this question is more subtle than I thought at the beginning.]

Declaring a pointer to a constant or a reference to const never helps the compiler to optimize anything. (Although see the Update at the bottom of this answer.)

A const declaration only indicates how the identifier will be used within its declaration; he does not say that the main object cannot change.

Example:

 int foo(const int *p) { int x = *p; bar(x); x = *p; return x; } 

The compiler cannot assume that *p not changed by calling bar() , since p can be (for example) a pointer to a global int and bar() can change it.

If the compiler knows enough about the calling element foo() , and the contents of bar() , which can prove that bar() does not change *p , then it can also perform this proof without declaring const.

But this is true in general. Since const only affects the scope of the declaration, the compiler can already see how you handle the pointer or link in that scope; he already knows that you are not modifying the base object.

In short, all const in this context do not allow you to make mistakes. It does not tell the compiler anything that it does not know yet, and therefore it has nothing to do with optimization.

What about functions calling foo() ? How:

 int x = 37; foo(&x); printf("%d\n", x); 

Can the compiler prove that this prints 37, since foo() accepts const int * ?

No. Even if foo() accepts a pointer to const, it can discard const-ness and change int. (This is not undefined behavior.) Here again, the compiler cannot make any assumptions at all; and if he knows enough about foo() to do such an optimization, he will know that even without const .

The only time const can allow optimization is the following cases:

 const int x = 37; foo(&x); printf("%d\n", x); 

Here, to change x to any mechanism (for example, by pointing to it and discarding const ), undefined Behavior is called. Therefore, the compiler may assume that you are not doing this, and it may propagate the constant 37 to printf (). Such an optimization is legal for any object that you declare const . (In practice, a local variable to which you will never accept a link will not be useful, because the compiler can already see if you are changing it in your area.)

To answer the question "side note", (a) the const pointer is a pointer; and (b) the const pointer may be NULL. You are right that the internal representation (i.e. Address) is most likely the same thing.

[update]

As Christoph points out in the comments, my answer is incomplete because it does not mention restrict .

Section 6.7.3.1 (4) of the C99 standard states:

During each execution of B, let L be any l-value that has & L based on P. If L is used to access the value of the object X that it denotes, and X is also modified (in any way), then the following requirements apply: T should not be const-qualified ....

(Here, B is the base unit over which P, a delimiter-pointer-to-T, is in the region.)

So, if the function C foo() declared as follows:

 foo(const int * restrict p) 

... then the compiler may assume that no changes to *p occur during the lifetime of p - that is, during the execution of foo() - because otherwise the Behavior will be Undefined.

So, in principle, combining restrict with a pointer to a constant can allow both optimizations that were fired above. I wonder if any compilers really implement such an optimization? (GCC 4.5.2, at least not.)

Note that restrict exists only in C, not C ++ (even C ++ 0x), except as an extension to the compiler.

+67
Jun 11 '11 at 3:11
source share

At the top of my head, I can think of two cases where the correct const -qualification allows for additional optimizations (in cases where analysis of the whole program is not available):

 const int foo = 42; bar(&foo); printf("%i", foo); 

Here, the compiler knows to print 42 without checking the body of bar() (which may not appear in the trace block), since all changes to foo are illegal (this is the same as the Nemo Example ).

However, it is also possible without marking foo as const , declaring bar() as

 extern void bar(const int *restrict p); 

In many cases, the programmer actually wants restrict -qualified pointers-to- const , rather than simple-to- const pointers as function parameters, since only the first ones provide any guarantees regarding the variability of pointed -objects.

As for the second part of your question: for all practical purposes, a C ++ link can be considered as a constant pointer (rather than a pointer to a constant value!) With automatic indirectness - it is not β€œsafer” or β€œfaster” than a pointer, it’s just more convenient.

+6
Jun 11 2018-11-11T00:
source share

In C ++, there are two problems with const (regarding optimization):

  • const_cast
  • mutable

const_cast means that even if you pass an object using a const or const reference, the function can discard const-ness and change the object (allowed if the object is not a constant to start with).

mutable means that even if the object is const , some of its parts can be changed (caching behavior). In addition, objects that point to (instead of being the owner) can be modified in const methods, even if they are logically part of the state of the object. And finally, global variables can also be changed ...

const here to help the developer catch logic errors early.

+5
Jun 11 '11 at 9:00
source share

const-correctness usually does not help performance; most compilers did not even bother to track consistency outside the interface. Values ​​of variables like const can help, depending on the situation.

Links and pointers are stored exactly the same in memory.

+4
Jun 11 2018-11-11T00:
source share

It really depends on the compiler / platform (this can help optimize some compilers that have not yet been written, or on some platform that you never use). The C and C ++ standards do not say anything about performance that is different from the complexity requirements for some functions.

Pointers and references to const usually do not help to optimize, because in some situations it is possible to qualify the qualification const, and it is possible that the object can be modified using another non-constant reference. On the other hand, declaring an object as const can be useful, because it ensures that the object cannot be modified (even if it is passed to functions that the compiler does not know the definition). This allows the compiler to store the const object in read-only memory or cache its value in a centralized location, which reduces the need for copies and checks for changes.

Pointers and references are usually implemented in exactly the same way, but again this is completely platform dependent. If you are really interested, you should look at the generated machine code for your platform and the compiler in your program (if you really use a compiler that generates machine code).

+2
Jun 11 2018-11-11T00:
source share

It’s one thing if you declare a global variable const, it can be placed in a read-only part of a library or executable file and thus share it between several processes using read-only mmap. This can be a big win on Linux on Linux if you have a lot of data declared in global variables.

Another situation, if you declare a constant global integer or float or enum, the compiler can just put the inline constant, rather than use a variable reference. It is a little faster, I believe, although I am not a compiler specialist.

Links are just pointers below, realistic.

+1
Jun 11 '11 at 3:27
source share

This may help performance a bit, but only if you access the object directly through its declaration. Reference parameters, etc. They cannot be optimized, since there can be other paths to an object not originally declared const, and the compiler cannot determine at all whether the object you are referring to is actually declared as const or not, unless this declaration is used.

If you use a const declaration, the compiler will know what functions are created from the outside of the body, etc. can't change it, so you get the benefit there. And of course, things like const int are propagated at compile time, so there is a huge win (compared to just int).

Links and pointers are stored in exactly the same way, they just behave differently syntactically. Links are basically renames, and therefore they are relatively safe, while pointers can point to many different things and, therefore, are more powerful and error prone.

I assume that the const pointer will be architecturally identical to the link, so machine code and performance will be the same. the real difference is the syntax - the links are a cleaner, more intuitive syntax, and since you don't need the extra equipment provided by the pointer, the link will be stylistically preferable.

0
Jun 11 2018-11-11T00:
source share



All Articles