Вся проблема в инкременте. ++buf->num и потом buf->num-1. По стандарту очередность выполнения инкремента не определена.
Спасибо, вы совершенно правы! Меня немного запутали эти sequence points (на выходе и входе из realloc). Сейчас побольше почитал про них, и стало всё ясно. Действительно, никакие sequence points не помешают компилятору вычислить то дерево в угодном ему порядке.
Ну а так в каждом языке свои правила, поэтому, чтобы не забиваться себе голову, я взял себе за правило не писать код, который содержит выражения, значения которых зависят от порядка вычисления аргументов функций/операторов. Имхо, так получается и более читабельно, и надо меньше ячеек в мозгу занято хранением деталей.
Я предполагаю (сам никогда не участвовал ещё), что в реальных проектах намного эффективнее по совокупному времени, потраченному на код, писать в более читабельном стиле. Потому что там код не только пишут, но ещё и читают, причем много-много раз.
Однако во время изучения языка (чем я сейчас и занимаюсь) полезно покопаться во всех этих тонкостях. Хотя бы чтобы лучше понять, почему так всё-таки не надо писать
Хотите интересное упражнение? Соберите программу с "однострочниками", потом перепишите ее в человеческом виде, соберите снова и сравните два исполняемых файла. Объясните результат.
Предполагаю, что существенной разницы не будет. Но мне нравится писать такие выражения, потому что их писать быстрее! В смысле набора с клавиатуры. Да и какая-то своя эстетика у них есть
И да, я знаю, что пока время, затраченное например на эту тему с лихвой перебило все эти 2-3 секундные выигрыши
Пожалуйста, не пишите запутанный код, если вы видите меньше UB, чем компилятор видит (а он их видеть абсолютно не обязан, кстати, в отличие от вас).
Ну, это только пока. Как говорится, догоним и перегоним компилятор. Я вот только недавно сел серьезно изучать C, поэтому и создаю подобные темы, дабы изучить язык на хорошем уровне.
Тут же как, я считаю: если программист "на ты" с этими sequence points, undefined behaviour, unspecified behavior и прочими хаками, то он прекрасно будет понимать, как эффективно и правильно написать и без них, когда это нужно.
Кстати, если вы так любите короткий код, то зачем умножаете на sizeof(char)? Это ведь равно единице по определению оператора sizeof().
Согласен, спасибо! Теперь буду заменять на 1. Как-то в памяти просто засело, что на некоторых системах
может быть и 2 октета, и 0.5, вот и писал по привычке. Но это никакого отношения не имеет к sizeof(char), который всегда 1 по стандарту языка, как только что выяснилось