WEBVTT

00:00.120 --> 00:00.690
Hello again!

00:01.050 --> 00:04.050
In this video, we are going to look at constant expressions.

00:05.640 --> 00:11.730
A constant expression has a value which is evaluated at compile time, and which cannot be changed.

00:12.300 --> 00:15.420
So obviously, literals would be constant expressions.

00:16.260 --> 00:22.860
We can also have values which are computed entirely from literals. And we can have values which are computed

00:22.860 --> 00:24.540
from other constant expressions.

00:25.140 --> 00:30.870
So if you have a constant expression, it is basically some computation involving literals.

00:33.700 --> 00:37.690
We can also have a variable, which is a constant expression. For this,

00:37.690 --> 00:44.320
the variable has to be initialized from a constant expression, and the variable cannot be modified after

00:44.350 --> 00:45.310
being initialized.

00:46.850 --> 00:51.590
For example, 42 and 99 are literals, so they are constant expressions.

00:51.920 --> 00:57.860
"i" and "j" are initialized from constant expressions, and they cannot be modified after initialization.

00:58.310 --> 01:00.710
So "i" and "j" are constant expressions.

01:01.490 --> 01:06.800
Then "i + j" is a computation involving only constant expressions.

01:07.160 --> 01:10.070
So "i + j" is therefore a constant expression.

01:11.700 --> 01:17.670
So this means you could use "i + j" as the dimension of an array because the dimension of an array must

01:17.670 --> 01:19.050
be a constant expression.

01:21.500 --> 01:27.740
If we make "i" and "j" non-const, then they are still initialized from constant expressions, but

01:27.740 --> 01:30.500
they can now be modified after being initialized.

01:30.890 --> 01:37.730
So "i" and "j" are not constant expressions. And this will give a compiler error. Unless you are using g++,

01:38.180 --> 01:44.300
when you have to use the "-pedantic" option. Because g++ allows this as a non-standard extension.

01:47.010 --> 01:47.940
So here is the code.

01:47.940 --> 01:53.100
We have "i" and "j" initialized from 42 and 99, which are constant expressions.

01:53.910 --> 01:58.950
"i" and "j" cannot be modified after initialization, so they are constant expressions as well.

01:59.520 --> 02:05.190
And then "i" and "j" is a constant expression, and can be used for the dimension of the array.

02:07.480 --> 02:08.470
And then, that compiles.

02:08.710 --> 02:11.470
We just get a warning about the unused local variable.

02:13.670 --> 02:19.280
If I make "i" and "j" non-const, then they are no longer constant expressions. Because they can

02:19.280 --> 02:21.350
be modified after initialization.

02:22.340 --> 02:25.070
And then "i + j" is not a constant expression.

02:25.700 --> 02:29.210
And we get an error. "Did not evaluate to a constant".

02:30.990 --> 02:34.500
So let's look a bit more closely at what it means, for something to be const.

02:35.280 --> 02:38.940
The key word has been around, since the early days of C++.

02:39.960 --> 02:44.310
A variable, which is const, cannot be modified after being initialized.

02:45.180 --> 02:47.370
There are two ways to initialize a const variable.

02:47.970 --> 02:51.240
We can use a constant expression. So we have something like this.

02:51.240 --> 02:53.430
So i is actually a constant expression.

02:54.600 --> 03:00.810
We can also initialize a const variable for a value which is known at runtime. Because const just means you

03:00.810 --> 03:01.710
cannot change the value.

03:02.220 --> 03:07.110
So we could, for example, read something from the keyboard, and then use that to initialize a const

03:07.110 --> 03:07.500
variable.

03:08.760 --> 03:14.190
If we are talking about compile-time programming, which is the subject of this section, then this

03:14.190 --> 03:17.070
could be interesting, because the compiler will know the value of "i".

03:17.490 --> 03:22.800
On the other hand, this is no use. Because compilers have no way of knowing what users are going to do when

03:22.800 --> 03:23.580
the program runs.

03:24.690 --> 03:26.280
So we have two separate concepts here.

03:26.670 --> 03:31.590
And in C++11, we have a new keyword, for the constant expression concept.

03:32.160 --> 03:36.600
So the constexpr keyword means that a variable is a constant expression.

03:37.710 --> 03:42.210
This means that the variable is evaluated at compile time and cannot be modified.

03:42.960 --> 03:48.840
So with the variable "i", which we declared as const before, we can now declare this as constexpr, because

03:48.840 --> 03:50.370
"i" is a constant expression.

03:53.180 --> 03:58.700
So what are the differences between being const and being constexpr? A variable which is const

03:58.700 --> 03:59.930
cannot be modified.

04:00.290 --> 04:02.360
And this is mainly used for function arguments.

04:03.070 --> 04:09.710
We pass an argument by reference to const, or pointer to const, for efficiency and safety. And the compiler

04:09.710 --> 04:13.220
will make sure that the function cannot modify the argument.

04:15.960 --> 04:21.840
If we have a variable which is constexpr, this means the value is known at compile time, and cannot be

04:21.840 --> 04:22.410
modified.

04:23.070 --> 04:26.070
And we use that for computing the value of constants.

04:26.850 --> 04:32.850
And this is useful, because we can improve performance by doing calculations at compile time. Instead

04:32.850 --> 04:33.810
of when the program runs.

04:34.530 --> 04:35.940
Okay, so that s it for this video.

04:36.480 --> 04:37.320
I will see you next time.

04:37.320 --> 04:39.450
But until then, keep coding!
