LINUX.ORG.RU

Если вам не хватало UB в C, то вам принесли ещё

 ,


1

3

Привет, мои дорогие любители сишки!

Если вам начало казаться, что разработчики стандарата языка C стали предсказуемыми и больше не могут удивлять вас новыми идеями, то вы ошибались. В новом стандарте C23, комитет постановил:

— zero-sized reallocations with realloc are undefined behavior;

То есть вот это валидный код:

void *ptr = malloc(0);
free(ptr);

А вот это – UB:

void *ptr = malloc(4096);
ptr = realloc(ptr, 0); <-- хаха UB

И это несмотря на то, что в манах уже давно написано следующее:

If size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr)

Изменение вносится задним числом, наделяя кучу корректного (согласно документации glibc) кода способностью полностью изменить логику работы программы. Ведь это то, чего нам так не хватало!

В тред призываются известные эксперты по C: @Stanson и @alex1101, возможно они смогут нам объяснить, зачем разработчики стандарта C постоянно пытаются отстрелить себе обе ноги самыми нелепыми способами.



Последнее исправление: cumvillain (всего исправлений: 1)

Ответ на: комментарий от firkax

На -O0 будет сегфолт, на -O2 может быть разное, если компилятор раньше времени поймёт что там NULL.

Нет. Компилятор понимает, что там не может быть NULL, потому что разыменование NULL – это UB, а значит в коде его быть не может в принципе. Так написано в стандарте.

Возможно в мануале к опциям оптимизации это описано.

А, возможно, и не написано. Ссылка где?

В свою очередь, я могу привести ссылку на стандарт, где написано, что если код допускает разыменование NULL, то компилятор может генерить вообще любой треш и ад. Что он и делает в данном случае.

hateyoufeel ★★★★★
()

Если подумать с точки зрения семантики операций, то realloc изменение выделенного ранее куска памяти, то есть в случае успеха - должен быть не NULL указатель, а если память невозможно выделить, то вернуть NULL. В случае же размера 0 и простого освобождения памяти (то есть фактического free) так же будет возвращен NULL, что неотличимо от сбоя выделения новой памяти при размере >0.

Всё правильно сделали, что внесли данное поведение в UB.

Божественная сишечка становится всё лучше!

Psilocybe ★★★★
()
Последнее исправление: Psilocybe (всего исправлений: 2)
Ответ на: комментарий от hateyoufeel

Нет. Компилятор понимает, что там не может быть NULL, потому что разыменование NULL – это UB, а значит в коде его быть не может в принципе.

Ты null видишь? И я не вижу, а он есть.

FishHook
()
Ответ на: комментарий от FishHook

Нет. Компилятор понимает, что там не может быть NULL, потому что разыменование NULL – это UB, а значит в коде его быть не может в принципе.

Ты null видишь? И я не вижу, а он есть.

В том коде, что я привёл, NULL в районе static затесался. Просто потому что static переменные инициализированы нулями вообще все.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

это UB, а значит в коде его быть не может в принципе. Так написано в стандарте.

Во-первых в стандарте немного не так написано. А так что «компилятор может генерить вообще любой треш и ад». И поэтому во-вторых важно то, что конкретно делает компилятор. Шланг генерит трэш и ад. Ну ок, будем иметь в виду, что шланг – трэшовый компилятор.

Тут как с людьми. Есть некоторое количество людей, которые всё делают в рамках закона, но при этом конченые мудаки. Ну такое.

no-such-file ★★★★★
()
Ответ на: комментарий от hateyoufeel

Да какая разница? Мы программируем или паззлы разгадываем? Если я - разработчик - смог засунуть NULL туда, где его как бы не может быть, это очевидная дыра в дизайне языка. Если компилятор решил, что чего-то быть не может, а оно на самом деле может - эта дыра в стандартах. Нет?

FishHook
()
Ответ на: комментарий от no-such-file

Go часто описывают как “C-подобный язык” или «язык С XXI века”. От языка С Go унаследовал синтаксис выражений, конструкции управления потоком, базовые типы данных, передачу параметров в функции по значению, понятие указателей и, что важнее всего, направленность С на получение при компиляции эффективного машинного кода и естественное взаимодействие с абстракциями современных операционных систем.

Однако в генеалогическом древе Go есть и другие предки. Одно из сильнейших влияний на Go оказали языки программирования Никлауса Вирта (Niklaus Wirth), начиная с Pascal. Modula-2 привнесла концепцию пакетов; Oberon использует один файл для определения модуля и его реализации; Oberon-2 явился источником синтаксиса пакетов, импорта и объявлений (прежде всего, объявлений методов), которые он, в свою очередь, унаследовал от языка Object Oberon.

Может, послушать умных людей?

LongLiveUbuntu ★★★★★
()
Последнее исправление: LongLiveUbuntu (всего исправлений: 1)
Ответ на: комментарий от no-such-file

А что в других случаях гарантирует?

Если можешь тыкнуть разработчиков компилятора в стандарт и показать, что их компилятор ему не соответствует, то это, по крайней мере, гарантирует, что разработчики обязаны прислушаться (даже если потом пошлют). А вот если не нравится, что компилятор делает при UB, то разработчики имеют полное право сказать «Пишите без UB. Следующий!»

red75prim ★★★
()
Ответ на: комментарий от red75prim

по крайней мере, гарантирует, что разработчики обязаны прислушаться

ЛОЛ, с каких щей? Я тебе открою страшную тайну, никто никому ничем не обязан. Разработчики могут заявлять что компилятор соответствует стандарту X, и при этом положить на это хер. Ну это будет очень кривой и багованый компилятор. На этом всё. Хочешь пользуйся, хочешь нет.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от cumvillain

В итоге в одном стандарте будет написано что это UB, в другом не написано ничего, а в третьем glibc будет делать одно, а musl – другое. Все как мы любим :)

Всё так и было. Просто если раньше ты мог ныть, что компилятор ххх работает не по стандарту(по какому?), то сейчас ты сам удак, потому, что пишешь код не по стандарту. Всё правильно сделали, как ещё удаков криворуких программировать учить?

Loki13 ★★★★★
()
Ответ на: комментарий от Loki13

Всё так и было.

Было ID. Из этого можно было двигаться в разны стороны.

Просто если раньше ты мог ныть, что компилятор ххх работает не по стандарту(по какому?), то сейчас ты сам удак, потому, что пишешь код не по стандарту. Всё правильно сделали, как ещё удаков криворуких программировать учить?

Так сишники стандарт не читают. В итоге их код так и останется забагованным.

cumvillain
() автор топика
Ответ на: комментарий от cumvillain

Было ID. Из этого можно было двигаться в разны стороны.

А потом, будучи собранным на другом компиляторе(которго сейчас, при написании может ещё даже не существовать) твой код «отформатирует тебе \»(утрировать, так по полной), что ты будешь говорить?

Так сишники стандарт не читают. В итоге их код так и останется забагованным.

Можно и не читать стандарт, мне, чаще IDE подсказывает ворнингами, где я могу обосраться. И я все эти советы читаю и добавляю проверки\исправляю код.

В данной ситуации оно и так хрен пойми как работало(в этом компиляторе так, в том по-другому). Да, конечно, лучше бы такой код переставал собираться вообще, но это к сожалению не реализуемо.

Loki13 ★★★★★
()
Ответ на: комментарий от Loki13

Можно и не читать стандарт, мне, чаще IDE подсказывает ворнингами, где я могу обосраться. И я все эти советы читаю и добавляю проверки\исправляю код.

А куда людей так не делают.

В данной ситуации оно и так хрен пойми как работало(в этом компиляторе так, в том по-другому). Да, конечно, лучше бы такой код переставал собираться вообще, но это к сожалению не реализуемо.

Почему в Rust смогли, а в C – нет? Просто признаем, что в C23 весь код должен вести себя нормально и сильно убираем весь attack surface. Те, кто не согласен – пожалуйста, для вас есть C17. А в итоге мы опять имеем кашу из C standard, POSIX standard и отдельные варианты gnuc11. Кеклол.

cumvillain
() автор топика
Ответ на: комментарий от Loki13

Ну вообще UB - это когда твой код может совершенно легально пойти накачать порнухи и отправить на электронку шефу и приведение уже существующего кода к UB именно этим и чревато.

anonymous
()

Наверное с помощью препроцессора можно попытаться сделать свой код независимым от выкидонов стандартоидов, в разумных пределах конечно, не как Стив Борн.

luke ★★★★★
()
Ответ на: комментарий от cumvillain

Просто признаем, что в C23 весь код должен вести себя нормально и сильно убираем весь attack surface. Те, кто не согласен – пожалуйста, для вас есть C17.

Есть неиллюзорные шансы, что все останутся на С17 в случае такой постановки вопроса.

Loki13 ★★★★★
()
Ответ на: комментарий от Loki13

Есть неиллюзорные шансы, что все останутся на С17 в случае такой постановки вопроса.

все

Останутся упоротые фетишисты. Жирный бизнес с легаси, который сперва будет ныть что оно не нужно, а потом переедет. У нас уже был py2 -> py3. В итоге все переехали и про py2 никто и не помнит.

cumvillain
() автор топика
Ответ на: комментарий от anonymous

Ну вообще UB - это когда твой код может совершенно легально пойти накачать порнухи и отправить на электронку шефу и приведение уже существующего кода к UB именно этим и чревато.

Ну это же только за ради поговорить мы так можем это воспринимать, а по факту, разработчики компиляторов вполне вменяемые люди.

Да, как выше приводили пример, выкинуть кусок кода наверное где-то компилятор и сможет, и то не факт, что в случае UB в стандарте, хоть один компилятор так делает(может, но делает ли?) при оптимизации.

Loki13 ★★★★★
()
Ответ на: комментарий от Loki13

Да, как выше приводили пример, выкинуть кусок кода наверное где-то компилятор и сможет, и то не факт, что в случае UB в стандарте, хоть один компилятор так делает(может, но делает ли?) при оптимизации.

Вон код выше, который не выдает ни одного варнинга, зато удаляет тебе /.

cumvillain
() автор топика
Ответ на: комментарий от Loki13

Таки речь не о том, что оно реально порнуху шефу пошлёт, а о том, что разработчики компиляторов хоть и вменяемые - но UB есть UB и если там в результате какого-то бага начнет происходить дичь однажды - это никто фиксить уже не будет.

anonymous
()
Ответ на: комментарий от cumvillain

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

Ага, переедет, на какой-нибудь другой язык(легаси же всё равно выкидывать). Вы, адепты раста, наверное об этом только и мечтаете. А тут какой-то UB, вместо нового фашистского стандарта, на который все положат.

Loki13 ★★★★★
()
Ответ на: комментарий от Loki13

Ага, переедет, на какой-нибудь другой язык(легаси же всё равно выкидывать). Вы, адепты раста, наверное об этом только и мечтаете. А тут какой-то UB, вместо нового фашистского стандарта, на который все положат.

Повторюсь, у нас есть опыт py3. Вой стоял – мама не горюй. Переехали.

cumvillain
() автор топика
Ответ на: комментарий от anonymous

но UB есть UB и если там в результате какого-то бага начнет происходить дичь однажды - это никто фиксить уже не будет.

Примерно так было с memmove, разработчиками флеша и щелкающим звуком. Ну и что? Поныли, поныли и исправили(те, кто должны исправлять, а не разработчики компилятора\glibc).

Loki13 ★★★★★
()
Последнее исправление: Loki13 (всего исправлений: 1)

Во-первых, нужно понимать что экосистема даже такого древнего уродства как C развивается, и ничего не вырублено в камне, поэтому требовать одинакового поведения в течение десятилетий - расписываться в профнепригодности. Только не надо, пожалуйста, начинать ныть что ты ленивая амёба которой успевать за этим лень, мы это уже слышали. Задача сообщества и комитета не просто НЕ состоит в том чтобы делать жизнь таких как ты комфортной (тем более за счёт интересов всех остальных), задача сообщества и комитета чтобы сделать жизнь таких как ты адом. Только не надо, пожалуйста, начинать врать что такое отношение вредит сообществу, это тоже слышали. Сообществу нужен развивающийся язык и не нужны ленивые амёбы и низкокачественный софт который они пишут. Отличным примером был python2->3, когда язык взяли и облагородили, сделав идеально почти всё с чем были проблемы на тот момент, а всю шваль которая не смогла обновиться просто кинули, в итоге язык процветает.

Во-вторых, программисту, а отличие от амёбы, дана голова, чтобы понимать что malloc или realloc нуля это что-то странное и нелогичное что бы там не было написано в стандартах и манах. Если ты не способен понять эту, довольно очевидную, ситуацию, то что от тебя ожидать в менее очевидных и не задокументированных случаях? Ухитрился написать код который выделяет нисколько памяти, значит границы буферов не будешь проверять просто гарантировано.

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

anonymous
()
Ответ на: комментарий от soomrack

И что характерно, код лучше не стал. Как писали жопой прыгая на клаве, так и пишут.

Это не важно. Причем, в случае py3 ситуация сильно хуже – там менялось много валидного кода. Если у кого-то проект состоит из одного сплошного UB, то вопрос переезда на C23 в этом случае наверное не самое важное.

cumvillain
() автор топика
Ответ на: комментарий от cumvillain

Повторюсь, у нас есть опыт py3. Вой стоял – мама не горюй. Переехали.

Как я помню, больше воя было от пользователей, которые ныли о зоопарке версий, а не от разработчиков. Разработчикам на py2 ныть не надо было, они или переводили проекты(живые) на py3 или проекты(а таких не мало) так и померли.

Loki13 ★★★★★
()
Ответ на: комментарий от anonymous

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

Внезапно не указывает в 99% случаев.

cumvillain
() автор топика
Ответ на: комментарий от Loki13

Как я помню, больше воя было от пользователей, которые ныли о зоопарке версий, а не от разработчиков.

s/пользователей/задротов/

Пользователям вообще плевать что там в зависимостях прилетает, они не знают про py2 vs py3 и это их не волнует абсолютно никак.

Разработчикам на py2 ныть не надо было, они или переводили проекты(живые) на py3 или проекты(а таких не мало) так и померли.

Программистов-задротов очень много. Это удивительно или что?

cumvillain
() автор топика
Ответ на: комментарий от Loki13

Ну и питон это на тот момент были или обертки вокруг сишных библиотек, которые переписать не особо сложно, или вебпроекты, которые поддерживали пока они не перестали быть актуальными и не пришла пора их полностью переделать.

soomrack ★★★★★
()
Ответ на: комментарий от Loki13

Ага, но ныли они не как программисты, а как пользователи.

Ныли они как техноэнтузиасты. Мне вот вообще было насрать какая там версия питона у софта в зависимостях.

cumvillain
() автор топика
Ответ на: комментарий от cumvillain

Пользователям вообще плевать что там в зависимостях прилетает, они не знают про py2 vs py3 и это их не волнует абсолютно никак.

Если разработчик позаботился о правильном распространении ПО, то да. Проблема в том, что таких разработчиков немного, и пердолиться с версиями и зависимостями приходится самим пользователям.

Xintrea ★★★★★
()
Ответ на: комментарий от soomrack

Вспоминая, меня на тот момент беспокоил транспорт Mailru.Agent для Jabber'a(и вроде ещё какой-то транспорт). Он был на py2 и никто на py3 переписывать его не собирался. Из-за него мне на VPS(где у меня был jabber-сервер мой) приходилось держать 2 питона. С тех пор и майлагент помер и даже jabber.

Loki13 ★★★★★
()
Ответ на: комментарий от Xintrea

Если разработчик позаботился о правильном распространении ПО, то да. Проблема в том, что таких разработчиков немного, и пердолиться с версиями и зависимостями приходится самим пользователям.

pip2 install vs pip3 install?

cumvillain
() автор топика
Ответ на: комментарий от cumvillain

где-то я выпал из «большей части софта», уже и не помню что собирал без указания стандарта. энивей, все может быть. я прст не понимаю, это ж рандом какой-то. сегодня собралось, завтра дефолтом другой стандарт и алё.

olelookoe ★★★
()
Ответ на: комментарий от olelookoe

где-то я выпал из «большей части софта», уже и не помню что собирал без указания стандарта. энивей, все может быть. я прст не понимаю, это ж рандом какой-то. сегодня собралось, завтра дефолтом другой стандарт и алё.

Нового мажорного стандарта не выходило с 2011 года. Это 13 лет уже.

cumvillain
() автор топика