Это [0] безопасно в С++?

Этот более ранний вопрос спрашивает, что означает this[0] в С#. В С++ this[0] означает "нулевой элемент массива, на который указывает this".

Гарантируется ли, что поведение undefined на С++ не вызывает обращение к объекту приемника таким образом? Я не сторонник использования этого синтаксиса, и мне в основном любопытно, гарантирует ли это спецификацию всегда.

Спасибо!

Ответы

Ответ 1

Для любого действительного указателя объекта p, p[0] эквивалентен *p. Итак, this[0] эквивалентно *this. Нет ничего более. Так же, как вы можете разыменовать любой действительный указатель, используя [0], вы можете разыменовать this с ним.

Другими словами, это просто "сложный" способ написать *this. Его можно использовать для обфускации кода. Его можно, вероятно, использовать и в некоторых конкретных обстоятельствах для полезных целей, так как любой отдельный объект можно рассматривать как массив размером 1. (From С++ 03, Additive operator: "Для целей этих операторов указатель к объекту nonarray ведет себя так же, как указатель на первый элемент массива длиной один с типом объекта как его тип элемента." )

P.S. Как отметил Йоханнес в комментариях, используя возможности С++ 11, можно создать контекст, в котором this является указателем на неполный тип. В этом случае выражение this[0] становится недействительным, а выражение *this остается в силе.

Ответ 2

this[0] - это то же самое, что и *(this + 0), так что это прекрасно (хотя и немного странно).

Ответ 3

Да, это то же самое, что *this

Ответ 4

AFAIK в основном this[0] точно такой же, как *this, поскольку this является просто нормальным указателем. Поэтому да, это безопасно использовать.

array[1] будет таким же, как *(array + 1) (когда array действительно) fyi...

Ответ 5

Он эквивалентен (по определению) до *(this + 0), что совпадает с *this. Это безопасно и четко, но странно.

Ответ 6

this[0] совпадает с *(this + sizeof(this)*0), поэтому он вполне безопасен

Добавлен небольшой тест в качестве ответа на комментарий

struct A
{
    void * _a;
    int _b;

    A * getThis(int index)
    {
        return &(this[index]);
    }
};

int main(int argc, char * argv[])
{
    A mas[100];

    std::cout << ((long long) mas[0].getThis(50) == (long long) &(mas[50])) << std::endl;
    return 0;
}