I am learning about the this
pointer in C . And i came across the following statement from the standard:
An expression
e
is a core constant expression unless the evaluation ofe
, following the rules of the abstract machine, would evaluate one of the following expressions:
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part ofe
;
I do not understand the meaning of the above quoted statement. I thought that the this
pointer is a runtime construct and so it cannot be used in compile-time contexts. But the above statement seems to suggest otherwise in the mentioned contexts. My first question is what does it mean. Can someone give some example so that i can understand the meaning of that statement.
I tried to create an example to better understand the meaning of the statement by myself but the program did not work as expected(meaning that it gave error while i thought that it should work according to the quoted statement):
struct Person
{
constexpr int size()
{
return 4;
}
void func()
{
int arr[this->size()]; //here size is a constexpr member function and so "this" should be a core constant expression and arr should not be VLA
}
};
In the above program, i thought that we're allowed to use the expression this->size()
as the size of an array(which must be a compile time constant) because size
is constexpr and so the quoted statement applies and so the program should compile. Also, since size
is constexpr arr
should not be VLA. But to my surprise, the arr
seems to be VLA and the program also doesn't compile in msvc(because msvc don't have vla i think). So my second question is why doesn't the quoted statement applicable in the above example and why is arr
VLA? I mean size
is constexpr so arr
shouldn't be VLA.
CodePudding user response:
The only way to use this
in a core constant expression is to call a constructor (and use it in the constructor) or call a member function on an existing object.
this
except in a constexpr function or a constexpr constructor that is being evaluated as part ofe
;
(emphasis added)
In your attempt, the constant expression should be this->size()
, but Person::func
(the function this
appears in) is not being evaluated as a part of that expression.
An simple example of what this allows:
struct S {
int i = 0;
constexpr S(int x) {
this->i = x;
}
constexpr int get_i() const {
return this->i;
}
};
// `this` used in constructor
constexpr S s{7};
// `this` used in `S::get_i`
static_assert(s.get_i() == 7);
static_assert(S{4}.get_i() == 4);