Удивительное рядом, но оно не определено
Oct. 13th, 2016 12:39 amЗадачка для оптимизирующих программистов (по крайней мере на C++)
В предположении, что компилятор делает все разрешенные стандартом оптимизации, что будет (если будет) напечатано в результате выполнения следующего участка кода (обвязку пишите сами):
В предположении, что компилятор делает все разрешенные стандартом оптимизации, что будет (если будет) напечатано в результате выполнения следующего участка кода (обвязку пишите сами):
int *p = (int*)malloc(4);
int *q = (int*)realloc(p, 4);
*p = 1;
*q = 2;
if (p == q) {
printf("%d %d\n", *p, *q);
}
no subject
Date: 2016-10-13 08:18 am (UTC)no subject
Date: 2016-10-13 02:50 pm (UTC)no subject
Date: 2016-10-13 03:25 pm (UTC)Стандарт (да благословит его Аллах) не определяет что такое "оптимизации" и как именно эти оптимизации делаются. Применение оптимизации не меняет наличия или отсутствия UB.
(no subject)
From:(no subject)
From:(no subject)
From:Хм
Date: 2016-10-13 08:21 am (UTC)Но доступные мне (различные) компиляторы делали одно и то же:
2 2
Re: Хм
Date: 2016-10-13 02:49 pm (UTC)no subject
Date: 2016-10-13 08:22 am (UTC)Оговорка: я не сильно много знаю про xx-rated C, так что глядел на это в парадигме C.
no subject
Date: 2016-10-13 02:48 pm (UTC)no subject
Date: 2016-10-13 08:22 am (UTC)Кстати, ролик вышел некоторое время назад (блин, там столько вывалили! смотреть - не пересмотреть), можно было не ходить, а смотреть тюбик в халате и тапках, попивая чай.
no subject
Date: 2016-10-13 02:47 pm (UTC)no subject
Date: 2016-10-13 06:40 pm (UTC)(no subject)
From:no subject
Date: 2016-10-14 04:59 pm (UTC)CppCon 2016
Date: 2016-10-14 06:57 pm (UTC)Обсуждаемое есть на видео в списке (“My Little Optimizer: Undefined Behavior is Magic").
Re: CppCon 2016
From:no subject
Date: 2016-10-13 11:04 am (UTC)Тогда программа напечатает: "2 2\n"
no subject
Date: 2016-10-13 11:15 am (UTC)Забавно)
no subject
Date: 2016-10-13 02:39 pm (UTC)no subject
Date: 2016-10-13 11:15 am (UTC)Отыгрываю Omniscient Omnipotent Lawful Evil компилятор. Предполагаю
sizeof(int)≤ 4, иначе всё ещё интереснее.В первой строчке
mallocможет вернутьnullptr, если памяти нет, или ненулевой указатель на область памяти не менее 4 байт.Во второй строчке
reallocможет вернуть (a)nullptr, еслиp == nullptrи памяти всё ещё нет; (b) указательp; или же (c) указатель, отличный отp, если реализация стандартной библиотеки не связана ограничением делать все разрешённые оптимизации. В последнем случае указательpстановится невалидным.В третьей строчке делается разыменование указателя
pбез проверки, что он не нулевой и валидный, варианты (a) и (c) ведут к UB.В качестве разрешённой оптимизации предполагаем, что UB не происходит — память всегда есть, а realloc не реаллочит по пустякам. Далее везде считаем, что
p == q.Раз
p == q, то запись единицы в третьей строке избыточна. Выоптимизируем её.В четвёртой строке пишем двойку, если escape-анализ покажет, что значение указателя
pилиqкуда-то выходит из рассматриваемого фрагмента. Если же не выходит, то никто не может легально получить доступ к этой памяти, поэтому запись в память тоже выоптимизируем, а в следующих трёх строчках будем делать вид, что записали.В пятой строке проверку пропустим, поскольку в рамках сделанных уже предположений условие всегда истинно.
В шестой строке память не читаем. Используем тот факт, что мы только что сделали вид, что записали туда двойку, а переменная не volatile. Форматную строку
"%s %s\n"в объектник не пишем, поскольку результат форматирования известен на этапе компиляции. Вызов printf заменяем наputs("2 2\n").no subject
Date: 2016-10-13 02:44 pm (UTC)no subject
Date: 2016-10-13 03:38 pm (UTC)no subject
Date: 2016-10-13 03:51 pm (UTC)no subject
Date: 2016-10-13 03:41 pm (UTC)Компилятор может не думать о реаллоке и предпооагает q отдельной областью памяти
no subject
Date: 2016-10-13 03:49 pm (UTC)no subject
Date: 2016-10-13 03:50 pm (UTC)(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-10-15 09:16 pm (UTC)#include <stdio.h> #include <stdlib.h> #include <stdint.h> int main(void) { int* p = malloc(sizeof(int)); uintptr_t ap = (uintptr_t)p; int* q = realloc(p, sizeof(int)); // *p = 1; *(int*)ap = 1; *q = 2; // if (p == q) if ((int*)ap == q) { // printf("%d %d\n", *p, *q); printf("%d %d\n", *(int*)ap, *q); } return 0; }no subject
Date: 2016-10-15 09:58 pm (UTC)В принципе, любое поведение компилятора можно объяснить фразой "изощрён, но не злонамерен".
(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:(no subject)
From:no subject
Date: 2016-10-16 12:38 am (UTC)