Удивительное рядом, но оно не определено
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)Хм
Date: 2016-10-13 08:21 am (UTC)Но доступные мне (различные) компиляторы делали одно и то же:
2 2
no subject
Date: 2016-10-13 08:22 am (UTC)Оговорка: я не сильно много знаю про xx-rated C, так что глядел на это в парадигме C.
no subject
Date: 2016-10-13 08:22 am (UTC)Кстати, ролик вышел некоторое время назад (блин, там столько вывалили! смотреть - не пересмотреть), можно было не ходить, а смотреть тюбик в халате и тапках, попивая чай.
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 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:39 pm (UTC)no subject
Date: 2016-10-13 02:44 pm (UTC)no subject
Date: 2016-10-13 02:47 pm (UTC)no subject
Date: 2016-10-13 02:48 pm (UTC)Re: Хм
Date: 2016-10-13 02:49 pm (UTC)no subject
Date: 2016-10-13 02:50 pm (UTC)no subject
Date: 2016-10-13 03:25 pm (UTC)Стандарт (да благословит его Аллах) не определяет что такое "оптимизации" и как именно эти оптимизации делаются. Применение оптимизации не меняет наличия или отсутствия UB.
no subject
Date: 2016-10-13 03:35 pm (UTC)no subject
Date: 2016-10-13 03:38 pm (UTC)no subject
Date: 2016-10-13 03:40 pm (UTC)Но даже если принять вашу позицию, я не понимаю почему выдачу "1 2" вы считаете детерминистическим результом максимальной оптимизации? Почему, скажем, не "2 2"?
no subject
Date: 2016-10-13 03:41 pm (UTC)Компилятор может не думать о реаллоке и предпооагает q отдельной областью памяти
no subject
Date: 2016-10-13 03:47 pm (UTC)Это можно сравнить с выводом оптимальной по тому или иному критерию булевской функции на основе таблицы истинности, содержащей Х (неизвестное/произвольное значение).
В результате получается функция, результат которой никогда не равен Х, и совпадает с табличным значением для всех булевских значений в таблице.
Выдача "1 2" однозначно следует из информации, доступной компилятору.
no subject
Date: 2016-10-13 03:49 pm (UTC)no subject
Date: 2016-10-13 03:50 pm (UTC)no subject
Date: 2016-10-13 03:51 pm (UTC)no subject
Date: 2016-10-13 03:54 pm (UTC)no subject
Date: 2016-10-13 04:24 pm (UTC)С точки зрения стандарта, насколько я понимаю, это как удалить старый обьект, создать новый обьект.
Вероятно, если передать , p и q как параметры, то оптимизировать так уже нельзя
no subject
Date: 2016-10-13 06:40 pm (UTC)