This question already has answers here:
When should you use constexpr capability in C++11?
(15 answers)
Closed 6 years ago.
So I understand that the use of constexpr in C++ is for defined expressions that are be evaluated at compile time, and more obviously to declare a variable or function as a constant expression. My confusion comes from understanding any benefits of using it for simple functions that will not change.
Suppose you have a function to simply square a value...
int square(int x) {
return x * x;
}
Typically that will never change, or be overridden, however, I've seen people say that it would be better practice to instead define it as...
constexpr int square(int x) {
return x * x;
}
To me, this seems like such a trivial change. Can anyone enlighten me on serious advantages of declaring such simple expressions as constexpr?
The advantage of that change is that whenever x is known at compile time, result of square could be used to initialize constexpr variables or as a template argument.
Related
This question already has answers here:
C++ implicit conversions
(4 answers)
Closed 2 years ago.
I was practicing for one of my upcoming exams and I came upon a weird piece of code in an exercise. For context, it's one of those exercises where you have to determine whether the code will run or not, what's wrong with it etc. The code that I find weird is the following:
class A {
int x;
public:
A(int i = 0) { x = i;}
A operator+(const A& a) { return a.x + x;}
...\\ rest of the code is not relevant
};
Naturally, I assumed that the operator would generate an error, because it returns an int value, while its return-type is defined to be class A. However, after plugging the whole example in my IDE, to check whether I was right or not, not only was there no error thrown at the function declaration, but one later addition operation in the code actually "worked"(I'm using quotations marks because the value it returned was garbage, but it didn't throw any errors neither).
Why is this not throwing any errors?
int is implicitly convertible to A, via A(int) constructor. Your operator+ in effect performs return A{a.x + x};
This is not specific to overloaded operators - whenever an expression of one type is provided where another type is expected, the compiler is looking for ways to implicitly convert the former to the latter.
This question already has answers here:
Is f(void) deprecated in modern C and C++? [duplicate]
(6 answers)
Closed 6 years ago.
I have seen in C++ program, during function declaration if there is no parameter for the function void is declared as parameter like this:
int F1(void)
How is it different than:
int F1()
There is no difference. Using void is just a more explicit way to declare the same thing. Personally, I never use that syntax and rarely see anyone else use it either.
It's the same thing in C++, and is a holdover from C.
Here's an excerpt from the C++ 2003 standard (C.1.6):
Change: In C++, a function declared with an empty parameter list takes no arguments.
In C, an empty parameter list means that the number and type of the function arguments are unknown"
Example:
int f(); // means int f(void) in C++
// intf(unknown) in C
Rationale: This is to avoid erroneous function calls (i.e. function calls with the wrong number or type of arguments).
Effect on original feature: Change to semantics of well-defined feature. This feature was marked as “obsolescent” in C.
Both of them are exactly the same, leaving the argument field empty as () is the one I prefer, some prefer writing (void) just so that someone editing the code may be ensured that no arguments are required. Makes no difference though, just a readability thing.
This question already has answers here:
When should you use constexpr capability in C++11?
(15 answers)
Closed 9 years ago.
I have a class which contains three static constants,
static const int NUM_POINTS = 2000;
static const float LAKE_THRESHOLD = 0.3;
static const int NUM_LLOYD_ITERATIONS = 2;
In the header file. I realize that now in C++11 I have to use a constexpr but I can't figure out how to use them. Can anyone explain constexpr in a simple way?
constexpr can be used to mark an expression as compile-time constant. It extends to functions as well, so an arbitrarily deep call chain can be compile-time constant. This permits the compiler to substitute the constant value, rather than evaluating it unnecessarily at runtime.
See: http://en.cppreference.com/w/cpp/language/constexpr
This question already has answers here:
Use of 'const' for function parameters
(31 answers)
Closed 7 years ago.
I was reading my C++ book (Deitel) when I came across a function to calculate the volume of a cube. The code is the following:
double cube (const double side){
return side * side * side;
}
The explanation for using the "const" qualifier was this one: "The const qualified should be used to enforce the principle of least privilege, telling the compiler that the function does not modify variable side".
My question: isn't the use of "const" redundant/unnecessary here since the variable is being passed by value, so the function can't modify it anyway?
The const qualifier prevents code inside the function from modifying the parameter itself. When a function is larger than trivial size, such an assurance helps you to quickly read and understand a function. If you know that the value of side won't change, then you don't have to worry about keeping track of its value over time as you read. Under some circumstances, this might even help the compiler generate better code.
A non-trivial number of people do this as a matter of course, considering it generally good style.
You can do something like this:
int f(int x)
{
x = 3; //with "const int x" it would be forbidden
// now x doesn't have initial value
// which can be misleading in big functions
}
This question already has answers here:
Default constructor with empty brackets
(9 answers)
Closed 7 years ago.
Can you figure out what is wrong with the statement below?
GCC error states:
'type name' declared as function returning array
#define MACRO(a) (a)[1]
class index {
public:
typedef int index_type[2];
const index_type& operator[](int i) const;
};
int k = 0;
int i = MACRO(index()[k]);
btw: I know what is wrong, I thought it was amusing thing to share. Many thanks to litb, his explanation of previous gotcha helped to solve this error pretty quickly.
In the expanded line:
int i = (index()[k])[1];
(index()[k]) is interpreted as a cast expression, declaring a function that returns an array of length k of index. At least, that's what it looks like is happening. How gcc is manages to validly interpret the [1] as an expression, I'm not sure.
My guess would be there's an ambiguity in your syntax. The compiler might be looking at the expanded macro:
int i = (index()[k])[1];
And thinking that index is actually a non-member function declaration that returns an array, rather than construction of a temporary object of type index.
But that's just a guess... if you know the answer already, please enlighten us :)
When you apply your macro, it expands to:
class index
{
// ...
typedef int index_type[2];
const index_type& operator[](int i)const;
// ...
};
int k = 0;
int i = (index()[k])[1];
Now the problem (assuming that index::operator[] is public, and it is non-obvious from your code snippet that it is) is that the result of index::operator[] is returned by reference, and you are constructing the index() object as a temporary, and so, assuming your index::operator[] is implemented how I'm guessing you've implemented it (returning a reference to a member object), the result of index::operator[] will be invalid immediately after it is returned (as the temporary is destructed), and so you have undefined behavior.