LINUX.ORG.RU
Ответ на: комментарий от sambist

++i: Префиксный инкремент(декремент) возвращает увеличенное значение как результат операции. Является l-value.

i++: Постфиксный инкремент(декремент) возвращает старое значение как результат операции. Является r-value.

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

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

++а разворачивается в (а = а+1)

Нет, ++ это вполне себе оператор. Правда унарный.
Нельзя говорить, что тут что-то «разворачивается». Это оператор, а не пища для препроцессора.

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

i++: Постфиксный инкремент(декремент) возвращает старое значение как результат операции. Является r-value.

Ну ок, вернул он а, получилось а = а. Почему после всего этого он а не увеличит на единицу?

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

Нет, здесь не a=a, здесь такой порядок:

- выполняем a++ => создаем временный объект, в который записываем старое значение (10), потом увеличиваем a, в a теперь 11.

- возвращаем значение во временном объекте из операции a++. Это значение 10.

- выполняем операцию =. Значение из временного объекта (а у нас там записано 10) копируем в a.

- Вуаля! a = 10

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

Часто, кстати, предпочтительнее использовать префиксную форму из-за того, что в ее случае не создается временный объект.

grondek
()

В Си кстати тоже самое)

Потому как это есть постфиксная форма.

То есть, a сначала присваивается, а потом инкрементируется.

Так что никакого UB)

И a += 1 тебе в помощь, если что ;-)

Twissel
()
Последнее исправление: Twissel (всего исправлений: 1)
Ответ на: комментарий от sambist

Жесть

Почему? Вроде ж никто не обещал, что инкремент/декремент выполняется гарантированно до или после присваивания?

А так-то на самом деле всё логично, потому что a = a++ по своей сути — бессмысленная операция, не? Если бы ты хотел увеличить a, написал бы просто a++. Но ты написал a = a++, и что должен был делать компилятор?

А еще, по-моему, тут замешаны т. н. "точки следования", и тогда это похоже на UB. Но могу ошибаться.

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

Это почему вдруг? Согласился бы если бы было а++, но тут значение дальше не вернется, пока ++ не вычислится.

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

Пример 3. Неопределённое поведение.

i = i++ Указанное выражение не содержит ни одной точки следования, поэтому компилятор не может определить порядок вычисления операторов, соответствующий стандартам. Поведение зависит от реализации компилятора.

Так что это убэ походу.

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

Мне уже страшно использовать эту библиотеку.

warehouse.elem = realloc(warehouse.elem

cppcheck не зря на эту конструкцию ругается.

i-rinat ☕☕☕☕
()
Ответ на: комментарий от sambist

Стандарт не гарантирует порядок вычисления аргументов, он implementation defined. Когда ты делаешь

int a = 1;
foo(a, ++a);

, то возможны два варианта:

1. сначала вычислится ++a и на фрэйм стэка вызванной функции ляжет 2 и 2

2. сначала будет вычислен и передан первый аргумент a(=1), а потом ++a(=2)

ISO International Standard ISO/IEC 14882:2014
1.9.15
If a side effect on a scalar
object is unsequenced relative to either another side effect on the same scalar object or a value computation
using the value of the same scalar object, the behavior is undefined.
Shadow1251
()
Последнее исправление: Shadow1251 (всего исправлений: 1)
Ответ на: комментарий от sambist

Что на практике:

#include <iostream>

void foo(int a, int b)
{
    std::cout << "a = " << a
	      << ", b = " << b
	      << std::endl;
}

int main(int argc, char* argv[])
{
    int n = 1;
    foo(n, ++n);

    return 0;
}
alex@localhost tmp % g++ --version
g++ (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
alex@localhost tmp % g++ -Wall c.cc
c.cc: In function ‘int main(int, char**)’:
c.cc:19:16: warning: operation on ‘n’ may be undefined [-Wsequence-point]
     foo(n, ++n);
                ^
alex@localhost tmp % ./a.out 
a = 2, b = 2
alex@localhost tmp % clang++ --version                     
clang version 3.5.0 (tags/RELEASE_350/final)
alex@localhost tmp % clang++ -Wall c.cc 
c.cc:19:12: warning: unsequenced modification and access to 'n' [-Wunsequenced]
    foo(n, ++n);
        ~  ^
1 warning generated.
alex@localhost tmp % ./a.out 
a = 1, b = 2

Shadow1251
()
Ответ на: комментарий от i-rinat

Раньше не ругался, сейчас отказывается работать, ссылаясь на неустановленную --data-dir, устанавливать оную отказывается.

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

Damn... Просмотрел :)

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

i-rinat ☕☕☕☕
()
Ответ на: комментарий от i-rinat

И где здесь выверты? Функция принимает 2 параметра, первый - указатель, второй - новый размер. ПРи вычислении нового размера сначала увеличивается размер в штуках, потом передается в функцию вычисленный в байтах. В чем проблема прочитать две строчки?

sambist
() автор топика
Ответ на: комментарий от i-rinat

Переинсталлил свой цппчек:

alex@laptop:~$ cppcheck ~/Сервер/Dropbox/Projects/Smilodon/Smilo/local/smlwarehouse.c 
Checking /home/alex/Сервер/Dropbox/Projects/Smilodon/Smilo/local/smlwarehouse.c...
alex@laptop:~$ cppcheck ~/Сервер/Dropbox/Projects/Smilodon/Smilo/local/
Checking /home/alex/Сервер/Dropbox/Projects/Smilodon/Smilo/local/smlhandlers.c...
1/2 files checked 66% done
Checking /home/alex/Сервер/Dropbox/Projects/Smilodon/Smilo/local/smlwarehouse.c...
2/2 files checked 100% done
Показывай пруфы, что ругается.

sambist
() автор топика
Ответ на: комментарий от i-rinat

warehouse.elem = realloc(warehouse.elem

cppcheck не зря на эту конструкцию ругается.
i-rinat ★★★★★ (19.04.2015 22:20:26)

Потому что иначе это п*добольство.

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

И где здесь выверты?

Использование префиксного инкремента и есть выверт. Он заставляет думать над выражением не секунду, а пять.

i-rinat ☕☕☕☕
()
Ответ на: комментарий от sambist

Потому что иначе это п*добольство.

Оспаде, да ради бога.

i-rinat ☕☕☕☕
()

Всё правильно. Сначала он возвращает 10, потом увеличивает значение а на 1, но в а записывается 10.

Используй префиксный инкремент.

anonymous
()
Ответ на: комментарий от sambist
$ cppcheck test.c
Checking test.c...
[test.c:5]: (error) Memory leak: p
$ cat test.c
int main()
{
        int *p = NULL;
        p = realloc(p, 10);
}

Тут и без cppcheck'а видна классика утечек, тащемта.

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

Используй префиксный инкремент.

анонимус совсем больной стал. ЗАЧЕМ? Что-бы записать в a то, что было ДО операции над a?! Это идиотизм ИМХО.

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

Вообще C++ позволяет решать одну и туже задачу разными способами.

да, но выбирать необходимо самый читаемый. Лично я считаю, что конструкция a++ нужна ТОЛЬКО для

x = array[index++];
и не для чего более.

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

а как же for ?

это частный случай перечисления. Для того и придумано. А вот просто так «прибавить единицу», дык возьми и прибавь. На кой ляд выёживаться?

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

Тебе в голову не приходило, что это не весь код?

    SmlElement * ptrold = warehouse.elem;
 
    warehouse.elem      = realloc(warehouse.elem,
                                  ++warehouse.elemcount * sizeof(SmlElement));
    if (!(warehouse.elem))
    {
        warehouse.elem = ptrold;
        *index         = 0;
        warehouse.elemcount--;
        return SML_ERR_BADALLOC;
    }

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

а как со скоростью выполнения?

монопенисуально. Компилятор в курсе, можешь проверить, objdump в помощь.

ЗЫЖ да, речь о amd64 & IA-32. Для других не ручаюсь. Т.е. думаю также, но не проверял.

emulek
()
Последнее исправление: emulek (всего исправлений: 1)
Ответ на: комментарий от sambist

Ну ок, вернул он а, получилось а = а. Почему после всего этого он а не увеличит на единицу?

Так тоже имеет право, типичный UB.

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

a++ создает временный объект со старым значением

Это особенность реализации твоего компилятора. Если ты рассчитываешь на вызов какого-нибудь конструктора в такой ситуации - ССЗБ.

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

Я не упоминал конструктор. Уж как он там его создаст - внутреннее дело компилятора.

grondek
()

Лурк море, Люке, таки UB. В новых плюсах, вроде, обещали избавиться от понятия точки следования (если я это сам только что не выдумал).

Upd: в педивикии прям явно твой вариант рассматривается, и назначается UB.

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

UB в С++ — это не недостатки компилятора, а фича языка.

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

Тебе в голову не приходило, что это не весь код?

Молодец самбист, поставил на место быдлокодера неграмотного.

А теперь сдуй щеки и почитай нормальную документацию, вроде такого, начиная с

When using realloc(), be careful to avoid the following idiom:

size += 50; 
if ((p = realloc(p, size)) == NULL) 
	return (NULL);
anonymous
()
Ответ на: комментарий от anonymous

This can cause aberrant program behavior if the incorrect size value is used.

Если внутренняя переменная, к которой у пользователя нет доступа «сломалась», неправильный реаллок, который выскочит с null - самое последнее, о чем нужно будет беспокоиться.

sambist
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.