gcc, строгое искажение и [закрытые] страшные истории

51
задан whoan 23 April 2019 в 05:01
поделиться

1 ответ

Своей ужасной истории нет, но вот несколько цитат из Линуса Торвальдса (извините, если они уже есть в одной из ссылок в вопросе):

http://lkml.org/lkml/2003/2/26/158:

Date Wed, 26 Feb 2003 09:22:15 -0800 Тема Re: Некорректная компиляция без -fno-strict-aliasing From Jean Tourrilhes <>

On Wed, Feb 26, 2003 at 04:38:10PM +0100, Horst von Brand wrote:

Jean Tourrilhes <> said:

It looks like a compiler bug to me... Некоторые пользователи жаловались, что когда следующий код компилируется без -fno-strict-aliasing, порядок записи и memcpy инвертируется (что означает, что фиктивный len копируется в поток). Код (из linux/include/net/iw_handler.h) :

static inline char *
iwe_stream_add_event(char * stream, /* Поток событий */
 char * ends, /* Конец потока */
 struct iw_event *iwe, /* Полезная нагрузка */
 int event_len) /* Реальный размер полезной нагрузки */
{
 /* Проверьте, возможно ли это */
 if((stream + event_len) < ends) {
 iwe->len = event_len;
 memcpy(stream, (char *) iwe, event_len);
 stream += event_len;
 }
 return stream;
}

ИМХО, компилятор должен иметь достаточно контекста, чтобы знать, что переупорядочивание опасно. Любое предложение, как сделать этот простой код более пуленепробиваемым, приветствуется.

Компилятор волен считать, что char *stream и struct iw_event *iwe указывают на разные области памяти из-за строгого алиасинга.

Что верно, и что не является проблемой, на которую я жалуюсь.

(Заметка задним числом: этот код в порядке, но реализация memcpy в Linux была макросом, который приводил к long * для копирования в большие куски. При правильно определенном memcpy, gcc -fstrict-aliasing не может нарушить этот код. Но это означает, что вам нужен inline asm для определения ядра memcpy, если ваш компилятор не знает, как превратить цикл копирования байтов в эффективный asm, что было в случае gcc до gcc7)

И комментарий Линуса Торвальда к вышесказанному:

Jean Tourrilhes wrote: >

По-моему, это похоже на ошибку компилятора...

Как вы думаете, почему ядро использует "-fno-strict-aliasing"?

Люди из gcc больше заинтересованы в попытках выяснить, что может быть разрешено спецификациями c99, чем в том, чтобы заставить вещи действительно работать. код алиасинга, в частности, даже не стоит включать, это просто невозможно невозможно разумно указать gcc, когда некоторые вещи могут псевдонимы.

Некоторые пользователи жаловались, что когда следующий код компилируется без -fno-strict-aliasing, порядок записи и memcpy инвертируется (что означает, что фиктивное значение len копируется в поток).

Проблема" заключается в том, что мы инлайним memcpy(), и в этот момент gcc не будет не будет заботиться о том, что он может использовать псевдонимы, так что он просто изменит порядок и заявят, что это их собственная вина. Несмотря на то, что нет никакого разумного способа сообщить об этом gcc.

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

Я не собираюсь утруждать себя борьбой с этим.

Linus

http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg01647.html:

Type-based aliasing is stupid. Это настолько невероятно глупо, что даже не смешно. Оно сломано. И gcc взял это сломанное понятие и сделал его еще более сломанным, превратив его в "по букве закона", что не имеет никакого смысла.

...

Я точно знаю факт, что gcc переупорядочивал доступы на запись, которые были явно по одному и тому же адресу (статически). Gcc вдруг подумает, что

unsigned long a;

a = 5;
*(unsigned short *)&a = 4;

может быть переупорядочен, чтобы сначала установить его на 4 (потому что очевидно, что они не являются алиасами - читая стандарт), а затем, поскольку теперь присвоение 'a=5' было более поздним, присвоение 4 может быть полностью пропущено! И если кто-то пожалуется, что компилятор сошел с ума, люди из компилятора скажут: "Няа, няа, люди из стандартов сказали, что мы можем это сделать", совершенно не задаваясь вопросом, имеет ли это хоть какой-то смысл.

31
ответ дан 7 November 2019 в 10:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: