do “const” declarations help the compiler (GCC) pr

2020-07-09 06:46发布

问题:

Do const declarations help the compiler (GCC) produce faster code or are they only useful for readability and correctness?

Zed Shaw has argued that const is useless or is overused in C/C++:

Next is all the bizarre fascination with const. For some odd reason C++ loves to make you slap const on every part of a declaration, and yet I get the same end result as C: a function is called. (...)

(From: http://librelist.com/browser//mongrel2/2010/7/15/c-verses-c++/#770d94bcfc6ddf1d8510199996b607dd )

回答1:

In general const modifier on method, references and pointers can't be used to optimize code for a couple of reasons. The primary one is that const modifier, in those contexts, doesn't make any guarantees about the underlying data not changing, it just makes it harder to modify it. Here is a classic example

void M(const C& p1, C& p2) { 
  cout << p1.field << endl;
  p2.Mutate();
  cout << p1.field<< endl;
}

In this case it's very possible that p1.field is modified in this code. The most obvious case is that p1 and p2 refer to the same value.

C local;
M(local, local);

Hence there is no real optimization the compiler can do here. The const parameter is equally as dangerous as the non-const one.

The other reason why it can't really optimize is that anyone can cheat in C++ with const_cast.

class C { 
public:
  int field;

  int GetField() const { 
    C* pEvil = const_cast<C*>(this);
    pEvil->field++;
    return field;
  }
};

So even if you are dealing with a single const reference the values are still free to change under the hood.



回答2:

Yes. Here’s one concrete example. const makes it possible to pass arguments by const& rather than by value (which might require a costly copy). It’s important to realise that the alternative to pass-by-const& is not pass-by-& because the latter doesn’t allow temporaries to be bound. So, for instance, this code:

auto result = foo{1} + foo{2} + foo{3};

may call foo operator +(foo const&, foo const&) but it may not call foo operator +(foo&, foo&).

That way, const helps avoid copies.

But generally, const is a tool to ensure correctness, not to to aid optimisations.

Either way, Zed Shaw has no idea what he’s talking about. The rest of his rant is similarly misinformed, by the way.



回答3:

No, const does not help the compiler make faster code. Const is for const-correctness, not optimizations.

The C++ standard says that const items can't be modified, but also says that const_cast should remove the const modifier from an object and make it writable (unless it's located in actually read-only memory, in which case the behavior is undefined); as such const cannot mean, in general, that the target variable will not change.

I can only think of these two very narrow scenarios where having const produces faster code than not having it:

  • the variable is global with internal linkage (static) and is passed by reference or pointer to a function defined in a different translation unit (different file). In this case, the compiler cannot elide reads to it if it is not marked const;
  • the variable is global with external linkage (extern). Reads to a const extern can be elided inside the file that defines it (but nowhere else).

When const is applied to a global variable, the compiler is allowed to assume that the value will never change because it will place it in read-only memory, and this means undefined behavior if the program attempts to modify it, and compiler authors love to rely on the threat of undefined behavior to make code faster.

Note that both scenarios apply only to global variables, which probably make for a very minor portion of the variables in your program. To its merit, however, const implies static at the global level in C++ (this is not the case in C).

Someone above said that using const can make code faster because it's possible to use const references. I would argue here that what make the code faster is the use of a reference, not the use of const.

That said, I still believe const is a very sharp knife with which you can't cut yourself and I would advise that you use it whenever it's appropriate, but don't do it for performance reasons.



回答4:

Yes, const can (not guaranteed) help the compiler produce faster/more correct code. More so than not, they're just a modifier on data that you express to both the compiler and to other people that read your code that some data is not supposed to change. This helps the type system help you write more correct software.

More important than optimizations, they just prevent your own code and people using your code from writing to data you assume to be invariant.