Home > database >  Is this pointer always a runtime construct
Is this pointer always a runtime construct

Time:04-29

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 of e, 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 of e;

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
    }
    
};

Demo

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 of e;

(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);

Demo: https://godbolt.org/z/hea8cvcxW

  • Related