Are modern C++ compilers able to avoid calling a const function twice under some conditions?

后端 未结 5 871
被撕碎了的回忆
被撕碎了的回忆 2021-02-05 01:10

For instance, if I have this code:

class SomeDataProcessor
{
public:
    bool calc(const SomeData & d1, const SomeData & d2) const;
private:
    //Some n         


        
5条回答
  •  南方客
    南方客 (楼主)
    2021-02-05 01:53

    Yes, modern C compilers can elide redundant function calls if and only if they can prove that such an optimization behaves as-if the original program semantics were followed. For example, that means means they could eliminate multiple calls to the same function with the same arguments, if the function has no side-effects and if its return value depends only on the arguments.

    Now, you asked specifically about const - this is mostly useful to the developer, and not the coder. A const function is a hints that the method doesn't modify the object it is called on, and const arguments are hints that the arguments are not modified. However, the function may (legally1) cast away the const-ness of the this pointer or of its arguments. So the compiler can't rely on it.

    Furthermore, even if const objects passed to a function really were never modified within that function, and const functions never modified the receiver object, the method could easily rely on mutable global data (and could mutate such data). Consider, for example, a function that returns the current time, or which increments a global counter.

    So the const declarations help the programmer, not the compiler2.

    However, the compiler might be able to use other tricks to prove the calls are redundant:

    • The function may be in the same compilation unit as the caller, allowing the compiler to inspect it and determine exactly what it relies on. The ultimate form of this is inlining: the function body may be moved into the caller at which point the optimizer can remove redundant code from later calls (up to an including all the code from those calls entirely and perhaps all or port of the original call too).
    • The toolchain may use some type of link-time-optimization, which effectively allows the type of analysis described in the point above even for functions and callers in different compilation units. This could allow this optimization for any code present when the final executable is being generated.
    • The compiler may allow the user to annotate a function with an attribute that informs the compiler that it may treat the function as not having side-effects. For example, gcc provides the pure and const function attributes which inform gcc that the functions has no side effects, and depend only on their parameters (and on global variables, in the case of pure).

    1 Usually, as long as the object wasn't originally defined as const.

    2 There is at one sense in which const definitions do help the compiler: they can put global objects defined as const into a read-only section of the executable (if such a feature exists) and also combine such objects when they are equal (e.g., identical string constants).

提交回复
热议问题