|
|
|
Странное предупреждение |
|
|
|
Jun 5 2018, 05:52
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Есть такая строчка в коде Код for (i=0; i < size_to_take; i++) { DataBuffer[i] = (data_out[j++]<<8) | data_out[j++]; } Выскакивает предупреждение Цитата Warning[Pa079]: undefined behavior: variable "j" (declared at line 176) (or a value reached by some form of indirection through it) is modified more than once without an intervening В GCC компайлере такого предупреждения нет.Что надо переделать чтоб предупреждение исчезло?
|
|
|
|
|
Jun 5 2018, 05:58
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(scifi @ Jun 5 2018, 11:54) j++ два раза в одном выражении - это бяка. Результат выражения не определён. Не надо так делать. у меня тут выбора особо нету если только так Код DataBuffer[i] = (data_out[j++]<<8); DataBuffer[i] |= data_out[j++]; по моему так еще уродливей
Сообщение отредактировал Jenya7 - Jun 5 2018, 06:00
|
|
|
|
|
Jun 5 2018, 06:18
|
Беспросветный оптимист
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646
|
Цитата(scifi @ Jun 5 2018, 08:54) j++ два раза в одном выражении - это бяка. Результат выражения не определён. Не надо так делать. Не результат выражения, а порядок операций. а делать так действительно не надо. Чем меньше неоднозначностей в коде, тем лучше. Ещё рекомендую статический анализатор запускать
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jun 5 2018, 06:37
|
Гуру
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136
|
Цитата(Jenya7 @ Jun 5 2018, 08:58) по моему так еще уродливей Что мешает сделать так: Код DataBuffer[i] = (data_out[j] << 8) | data_out[j + 1]; j += 2; ??? И дело не в уродливости, а в корректности. Оригинальный код некорректен, слава яру и его предупреждениям. Цитата(MrYuran @ Jun 5 2018, 09:18) Не результат выражения, а порядок операций. То есть вы утверждаете, что результат определён? Какое смелое заявление.
|
|
|
|
|
Jun 5 2018, 07:09
|
Гуру
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136
|
Цитата(andrew_b @ Jun 5 2018, 09:49) Рискну предположить, что стандарт не говорит о результате. Он говорит о порядке операций. Неверное предположение. Конечно, стандарт говорит о результате, иначе зачем он нужен? Результат складывается из последовательности операций, и если порядок операций не определён, то и результат не определён. Очевидно же! Цитата(MrYuran @ Jun 5 2018, 10:07) В данном случае нет, но такое предупреждение бывает, например, при операциях с несколькими волатильными переменными Угу.
|
|
|
|
|
Jun 5 2018, 08:17
|
Профессионал
Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075
|
Цитата(scifi @ Jun 5 2018, 12:37) Что мешает сделать так: Код DataBuffer[i] = (data_out[j] << 8) | data_out[j + 1]; j += 2; ??? И дело не в уродливости, а в корректности. Оригинальный код некорректен, слава яру и его предупреждениям. То есть вы утверждаете, что результат определён? Какое смелое заявление. на этом варианте остановлюсь. спасибо.
|
|
|
|
|
Jun 5 2018, 13:24
|
Профессионал
Группа: Свой
Сообщений: 1 975
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757
|
Цитата(scifi @ Jun 5 2018, 10:09) Неверное предположение. Конечно, стандарт говорит о результате, иначе зачем он нужен? Цитата The grouping of operators and operands is indicated by the syntax.71) Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified. Оно?
|
|
|
|
|
Jun 20 2018, 07:19
|
Профессионал
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045
|
Цитата(Jenya7 @ Jun 5 2018, 10:52) Есть такая строчка в коде Код for (i=0; i < size_to_take; i++) { DataBuffer[i] = (data_out[j++]<<8) | data_out[j++]; } если нет перевёртывания с эндианами и DataBuffer - это 16-ти разрядное, то Код memcpy((void*)DataBuffer, (void*)&data_out[j], 2*size_to_take); j += 2*size_to_take; //если j дальше не нужно, удалить эту строку без ворнингов, безопаснее, и БЫСТРЕЕ. (явное преобразование к воид не обязательно).
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|