C отрицательный индекс массива

это моя структура:

struct Node {
    struct Node* data;
    struct Node* links[4];
}

Предполагая, что нет отступов, Node->links[-1] гарантированно указывает на Node::data?

Ответ 1

Нет гарантии; это поведение undefined:

  • Заполнение структуры, зависящей от компилятора
  • Стандарт определяет только индексирование массива между 0 и длиной (включительно)
  • Возможное нарушение строжайшего сглаживания

На практике, вполне возможно, что вы укажете на data, но любые попытки доступа к нему приведут к UB.

Ответ 2

Подстрока массива определяется в терминах арифметики указателя, а в стандарте C99 это говорит об арифметике указателя:

Если и операнд указателя, и результат указывает на элементы тот же объект массива или один прошлый последний элемент объекта массива, оценка не должна давать над потоком; в противном случае поведение undefined.

Таким образом, доступ к Node->links[-1] (даже просто получение адреса Node->links[-1]) - это поведение undefined, строго говоря. Поэтому у вас нет гарантии, что Node->links[-1] получит вас Node::data.

Но, как упоминают многие комментаторы, это будет работать почти всегда. Я все еще считаю это плохой практикой программирования, которой следует избегать. Если это не техничность, то из-за того, что изменения в struct Node могут привести к ошибкам, которые компилятор вам не поможет. Когда кто-то добавляет что-то между data и links, все будет таинственно ломаться.

Ответ 3

A union может помочь вам здесь. Что-то вроде этого:

struct Node {
  union {
    Node *data;
    struct {
      Node *lnk[5];
    } links;
  }
}

Ответ 4

Я бы сказал, да, но почему бы не объявить его как

struct Node {
    struct Node* links[5];
}

Ответ 5

Почти Да

Да, он почти наверняка укажет на data, но это может быть не совсем гарантия.

Фактически вы получаете гарантию, что x[-1] - это то же самое, что и *(x - 1), поэтому, в зависимости от того, что вы указали по адресу x - 1, у вас есть своего рода гарантия. (И не забывайте, что при вычитании из указателей декремент зависит от размера элемента.)

Хотя другие возражали по принципу строгой псевдонимы, в этом случае типы одинаковы, поэтому сложные оптимизации не должны устранять ожидаемое поведение.

Ответ 6

Думаю, что да. Но стандарт не гарантирует, что нет прокладки.

Изменить: но стандарт также говорит, что поведение undefined, если "Индекс массива вне диапазона, даже если объект, по-видимому, доступен с заданным индексом".

Ответ 7

Это реализация определена в зависимости от того, как структуры и массивы реализации реализуются. Тем не менее, до тех пор, пока он создает структуры и массивы одинаково, он должен работать.