Выравнивание указателей на аргументы функций в C ++ 17 - PullRequest
0 голосов
/ 01 июня 2018

Я вижу, что в C ++ 17 введены выровненные новые выражения с std::align_val_t для объектов, требующих большего выравнивания, чем предусмотрено в new.Это здорово, но заставило меня задуматься:

Почему выравнивание указателя не является частью типов указателя?

Например:

long foo(long *x) {
  return *x; // here, the compiler do an aligned load
             // correct as (long*) is expected to be aligned
}

Будетпредположим, что указатель выровнен на 64 бита (на моей машине).Но компилятор не предупредит меня, если я сделаю следующее:

long bar(char *x) {
  return foo((long*) x); // here, the compiler do an aligned load, risky!
}

long pop(char *z) {
  return bar(z + 1); // here, the compiler do an aligned load too!
}

Мне удалось получить предупреждение, передав указатель на поле из упакованной структуры:

struct ugly {
  char x;
  long y;
} __attribute__((packed));

long kun(ugly *a) {
  return a->y; // here, the compiler do an unaligned load, correct!
}

long zip(ugly *a) {
  return foo(&a->y); // here, the compiler do an aligned load, incorrect!
                     // but warns me about it.
}

Нопочему это не ошибка, сродни const_cast?

Что говорит стандарт в отношении выравнивания?

Все ли компиляторы делают неверные предположения илиЭто неопределенное / определенное реализацией поведение, чтобы дать невыровненный указатель на функцию?

Вы можете увидеть их в действии здесь: https://godbolt.org/g/9ddbiq

Редактировать : Исправлен фрагмент кодаи предоставил ссылку на Годблот.

1 Ответ

0 голосов
/ 01 июня 2018

Что говорит стандарт в отношении выравнивания?

Это просто: каждый существующий объект типа T имеет правильное выравнивание.

Если выиспользуйте размещение new и укажите указатель с недостаточным выравниванием, результаты UB.Если вы замените распределитель new и предоставите указатель с недостаточным выравниванием для выделяемого типа, то получится UB.Если ваш std::allocator<T>::allocate возвращает указатель, который не выровнен соответствующим образом к T, результат UB.И т. Д.

Неопределенное поведение не требует сбоя компиляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...