inline vs. constexpr?

12,407

Solution 1

Asserting that something can be computed at compile-time is a pretty strong kind of optimization.

Inlining merely removes a function call, by copy/pasting the function body into the call site. The function body still has to be executed, you just save the overhead of a function call.

But if you make the same code be evaluated at compile-time, it is free at runtime.

But neither inline nor constexpr are primarily about optimization. inline's main purpose is to suppress the one-definition-rule, so that functions can be defined in headers (which is useful for templates, and incidentally, also makes the inlining optimization easier)

And constexpr is there because it is useful in metaprogramming, and incidentally, it may help the compiler better optimize the code, by moving more computations to compile-time.

Solution 2

To quote wikipedia:

C++0x will introduce the keyword constexpr, which allows the user to guarantee that a function or object constructor is a compile-time constant.

Mark functions inline if they are super short. Mark functions as constexpr if the results are required at compile time. (Template parameters or array sizes). I believe a function can be both if needed.

A constant expression function or constructor can be called with non-constexpr parameters. Just as a constexpr integer literal can be assigned to a non-constexpr variable, so too can a constexpr function be called with non-constexpr parameters, and the results stored in non-constexpr variables. The keyword only allows for the possibility of compile-time constancy when all members of an expression are constexpr.

So, GCC is not incorrect in this.

Share:
12,407
RétroX
Author by

RétroX

@RetroXYZ

Updated on June 22, 2022

Comments

  • RétroX
    RétroX about 2 years

    With the new C++11 standard, when should I use the inline keyword over the constexpr keyword? Does the constexpr keyword offer any additional optimization over inline, or does it merely assert that things must be computed at compile-time?

    Why does constexpr work on the GCC in some cases where the call is not constant, such as calling foo(x) on a non-constexpr variable? Is this a bug in the GCC or is it actually part of the standard?

  • ildjarn
    ildjarn almost 13 years
    According to this question, when constexpr functions are not used in a context requiring a constant expression, the compiler is not obligated to compute the expression at compile-time.
  • josesuero
    josesuero almost 13 years
    but it still specifies that the computation can be performed at compile-time. So as with inline, it's not really about optimization, but it may provide additional information that the compiler can use to optimize.
  • ildjarn
    ildjarn almost 13 years
    Right, I was just nitpicking about use of the word "must". :-]
  • boycy
    boycy over 12 years
    @jalf I'd disagree that inline is not primarily about optimization. IIRC functions defined in a header file default to being inlined, though as is always the case with inline - it's merely a compiler hint. As long as you've got header guards in place then ODR isn't really relevant anyway. Willing to be educated here though :-)
  • rubenvb
    rubenvb about 11 years
    @boycy wrong: a missing inline in a header will violate the ODR: two source files using the same non-inline function defined in the header will cause a multiple definition error when linking them together. It is exactly inline that fixes that.
  • josesuero
    josesuero about 11 years
    @boycy: ODR has nothing to do with header guards. (The ODR is about multiple translation units defining the same symbol. Header guards protect against multiple definitions inside the same translation unit). And the compiler will inline whatever it feels like, regardless of the inline keyword. It can inline things that aren't marked inline and it is not required to inline that which you mark inline. So optimization-wise, the keyword doesn't really do anything.
  • josesuero
    josesuero about 11 years
    Where optimization enters into the picture is that if you mark something inline, then you can make its definition visible in every translation unit where it is used without causing an ODR violation, and that makes it easier for the compiler to perform the inlining optimization. So the keyword doesn't by itself enable any new optimizations, but using it allows you to changes to how your code is structured, and those changes can enable the compiler to optimize (although a modern compiler can do optimization across translation units and then tricks like this aren't necessary either)
  • M.M
    M.M over 6 years
    inline does not imply internal linkage as you seem to be saying in your first paragraph
  • SirGuy
    SirGuy over 6 years
    You mention that inline is useful for templates, but that isn't actually true, function templates and member functions defined inside the class are automatically treated as having the inline keyword before them. It's useful for free functions that will be defined in multiple translation units (usually due to being defined in a header file and included in different TUs) and avoiding the linker errors by telling the linker to discard all but one definition while linking.
  • Kit10
    Kit10 almost 3 years
    The inline keyword is treated as a "suggestion" to the compiler only (cplusplus.com/articles/2LywvCM9). Also, constexpr is "implicitly" inlined (en.cppreference.com/w/cpp/language/inline). There are so many other simpler/standard ways to resolve ODR issues in C++, I personally have never considered inline to resolve this. Neither of these (first two results in my Google) websites mentions ODR.