constexpr function------C + + Primer

Source: Internet
Author: User
Tags function definition

The constexpr function refers to a function that can be used for constant expressions. There are other functions that define the CONSTEXPR function, but there are several conventions to follow: The return value type of the function and the type of the formal parameter are literal types, and there must be only one return statement in the body of the function. To be able to expand at any time during the compilation process, the CONSTEXPR function is implicitly specified as an inline function.

The constexpr function body can also contain other statements, as long as these statements do nothing at run time. For example, you can have empty statements, type aliases, and using declarations in the CONSTEXPR function.

The return value of the Allow constexpr function is not a constant:

constexpr int scale (int cnt) {return 5*cnt;} If Arg is a constant expression, then scale (ARG) is also a constant expression

When the actual parameter of the scale is a constant expression, its return value is also a constant expression, or vice versa. If we call the scale function with a very expressive expression, such as an int type Object I, the return value is a very expressive expression. When the scale function is used in the context of a constant expression, it is the compiler's responsibility to check that the result of the function conforms to the requirements. If the result is not a constant expression, the compiler emits an error message. The CONSTEXPR function does not necessarily return a constant expression.

Put inline functions and constexpr functions inside the header file

Unlike other functions, inline functions and constexpr functions can be defined more than once in a program. After all, it is not enough for the compiler to have a function declaration to expand the function, but also to define the function. However, for a given inline function or constexpr function, its multiple definitions must be exactly the same, for this reason, inline functions and constexpr functions are usually defined in the header file.

Https://www.cufe-ifc.org/question/153643.html

C + + inline functions and constexpr functions can be defined more than once in a program, and when is this generally used? Tim Shen 2017-08-21318 Inline Functions C + +(c + + Primer, 5th edition, page 215) and the book says, "for a given inline function or constexpr function, its multiple definitions must be exactly the same." For this reason, inline functions and constexpr functions are usually defined in the header file. Why don't you put it in the source file? I used the online example (the inline keyword inline in C + +) to run: A.h #pragma once Class A {public:a (int A, int b): A (a), B (b) {} int max () private:in t A; int b; }; A.cpp #include "A.h" Inlin ... 0 0 Other answersCan be defined more than once the benefit is convenient for you to put in the head file, the advantage of the header file is that each include this header file. c files can function body, see the benefits of the function body is the compiler can inline. The benefit of inline is that the code gets faster. In addition, all function body definitions must be identical, otherwise the problem is not responsible. The constexpr comes with the inline property.

When you decide to define a function body in a. c file, you naturally don't need the inline keyword. And this time also must link corresponding. o to ensure that the definition is found.

-------------------------------Talk version------------------------------

Let's start with a few pre-built knowledge:

1) C and C + + have translation unit (or compilation unit) concept: Basically the compiler compiles one file at a time, forgets everything, and then compiles the next file. Even if you write Gcc-c a.c B.C, in fact, and Gcc-c A.C && gcc-c B.C generally no difference. At the end, all of the. o files are linker aggregated into a large executable file.

2) static function. You can mark a function as static (also known as internal linkage) so that the symbol of the function is hidden so that the function exists only in the current translation unit. After swapping the next translation unit, the function is forgotten. Linker never knew that this function existed. When you define a static function that was previously defined by translation, linker does not report a redefinition error. Of course, this code appears several times in binary.

3) Of course you also know that C and C + + include means: In a, # include <B> is to copy the contents of B to the location of # include.

4) The compiler inline optimization is to see you call Foo in the bar, to help you copy the function of Foo, embedded into the bar, while eliminating the overhead of the stack operation (because the code has been copied to "local", do not need to jump to jump). Inline optimization has a flaw, that is, in the same translation unit must see the function body, so light to see declaration is useless.

Now consider this: the traditional way of declaring in a header file that implementing a function body in a file (. c) is sometimes too slow. Why slow, suppose I this function on the line, but the function call of the stack of parameters, such as the stack jump, and so the instructions accounted for most of the cost, it is really not advantageous.

There are two solutions in traditional C:
1) "Macro function". is to put the function body hidden in the. c file into a macro, of course, the macro is also in the header file. Then everyone include the first file of the macro also include to go, use the macro when the code to spread over and over to all the use of the place, eliminating the overhead of function calls.
2) define the static function in the header file, in case the compiler supports inline optimizations. Any other. c file, as long as the include your header file, all of your header file has been copied and pasted, automatically obtained the static function body. So within the different translation unit, these functions do not conflict because they are static. It is worth mentioning that these function bodies are not necessarily identical. For example:
// a.h    #define FOO 3static int Foo() { return FOO; }// a.c#include "a.h"// b.c#undef FOO#define FOO 2#include "a.h"
inside a different translation unit, a Foo returns 31 returns 2.

1) The disadvantage is obvious, the macro can not solve the problem of type checking, the macro is dynamic scope (the variable check environment is the caller and not the definition end of), the macro is textual substitution, do not have to confuse the compilation does not pass, the macro is ugly, defined without syntax highlighting (fog), and so on.
2) It looks good, it's a real function, and the compiler has the ability to inline. The drawback is that when the compiler decides not to inline (usually at this time the function is large), each translation unit defines a large function, resulting in an unnecessary binary size bloat.

At this time, C + + Father Bjarne Stroustrup stand out, said we in C + + to make an inline keyword it! This keyword is not only known by the compiler, but when the compiler does not actually inline the function, it will somehow prompt linker to say that the function is marked as "repeatable definition" yes-based on my experiment with GCC, a weak symbol is generated. When linker sees a weak symbol, it writes the function name on a small laptop. At the end of the linker all the files link together, it will sweep the small books, for the same name function only one, the other function and function body all deleted. This solves the problem of binary size bloat. This is, of course, a typical implementation, not necessarily.

In addition, when the compiler actually inline the function, the effect is the same as static, which is why you cannot find the definition in your code-because linker does not see the static function at all. That said, but they don't care if it's called internal linkage (inline specifier), because linkage is a implementation detail at this point. Language only emphasizes:
The definition of an
inline function must was present in the translation unit where it was called (not necessarily BEF Ore
the point's call)

As mentioned earlier, the function body that included in the include static functions may not be exactly the same. Inline here also mentions that if you have a function of the same name is not the same as the length of the function, I will not tell you which one I want to delete which of the several. If you dare to do this, I do not guarantee that my output is meaningful. This is called ODR violation (definitions and ODR) in C + +. The compiler sees only one translation unit at a time, so it's usually impossible to detect ODR violation (not to exclude LTO or to check), and linker doesn't look, I don't know why, it's probably too expensive.

In addition, you can feel the marketing slogan of the current year's inline keyword:
"An Inline Function is as Fast as a Macro" (Inline-using the GNU Compiler Collection (GCC))

Incidentally suggested brush acm-icpc of various pit father OJ classmate, want to speed on the macro, because OJ may not open inline optimization. Tim Shen 2017-08-21 14:33:180 Reviews 0 0 For inline functions, the larger feature is that it is directly expanded where the function is called, rather than a function call, thus reducing the call cost of the function. In the case of a function call, we can use the function, such as int foo (), and then let the following linker go to other target files to find the function symbol.

I'll take a closer look at the reasons behind this, I use GCC as a demonstration, because Linux has a range of tools that can be easily viewed, but this is consistent with the principles of Visual C + +.

Back to your example, we use g++-C http://main.cc-o MAIN.O and then use NM MAIN.O | C++filt to view the generated symbols as shown in:


We can clearly see that the A::max () symbol is u, that is, undefined, so it wants the linker to go somewhere else to find the definition of the function. If everything is normal, then we have a A.cpp, and then generate a A.O, the linker to A.O place can find this function definition.

However, we are going to compile its implementation file to view its symbol table:

We can see that there is no this symbol table, because as mentioned earlier, the inline function does not generate a function call, it will be expanded in the source file, so there is no sign of the function.

So it is, after the linker, when the resulting. O is merged together, A::max () is still undefined, as shown in:


So, what if it's not an inline situation?
We can find that A.O will produce A::max () function symbols, so if the linker goes to link MAIN.O a.o:
We will find that the A::max () of the undefined with the U mark is main.o and filled in the last. O.

So why is the function definition of inline placed in the header file? Because when we use, will include "A.h", then this time the compiler will first preprocess the deployment, this also includes the definition of A::max (), using g++-e http://a.cc > A.I; Vim A.I as shown below:

So this time, http://main.cc in the source file can find A::max () definition, and then let us look at the final symbol table:

And indeed, as we intend, not the undefined of U.

Well, here's a little more, in the modern C + + compiler, we almost all do an optimization called inline function optimization, because when we optimize, if it is not an IPA is a function to do, then our inline function optimization will expand the relevant definition in a function, This allows for better optimization. And this inline function optimization level, in each compiler is different, but in our actual implementation of C + + compiler, in fact, is not a lot of textbooks mentioned a few lines, we tend to be 100 rows, and even more functions will be inline expansion, is to better optimize. and our inline optimization, in fact, is based on how many lines of your function are decided, so in the modern C + + compiler, if you are for inline optimization and add inline, I think the meaning of the inline is completely unnecessary here, modern C + + Compiler optimizations have been very powerful. Therefore, if inline is discarded by C + + in the future, it is completely understandable.

constexpr function------C + + Primer

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.