|
|
  |
Cpp check ругается, можно ли так писать? |
|
|
|
Feb 6 2018, 14:36
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (ViKo @ Feb 6 2018, 16:30)  Так, жду-с. Вам уже дали правильный и исчерпывающий ответ: QUOTE (_pv @ Feb 6 2018, 15:34)  а может всё-таки сначала инкрементируете, потом считаете логарифм уже от следующего элемента, но результат записываете на место предыдущего? Компилятор имеет на это полное право. Чего еще вы ожидаете услышать?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Feb 6 2018, 14:43
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 6 2018, 16:39)  Здесь тоже сначала инкрементируют, потом записывают? while (*s++ = *t++) Здесь у Вас два разных указателя. А значит - нет неопределённости по операциям постинкремента. Если конечно у Вас в неких "первых строках", которые Вы не посчитали нужным привести здесь, не записано: #define t s
|
|
|
|
|
Feb 6 2018, 14:44
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(ViKo @ Feb 6 2018, 21:30)  Так, жду-с. Извольте. Стандарт С явно указывает что порядок вычисления левой и правой частей оператора присваивания не определён. Цитата 6.5.16 Assignment operators: 4. The order of evaluation of the operands is unspecified. А в С++ понаписали такого что и с бутылкой не разберёшь. Так что да, по крайней мере в С, никто не гарантирует что pSigRe во время вычисления правой части не окажется уже инкрементирован в результате случившегося раньше вычисления левой части оператора присваивания.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Feb 6 2018, 14:45
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 6 2018, 16:22)  Ладно. Значит, нужно найти точное толкование, когда инкрементируется указатель, если он используется справа и слева от оператора присваивания. Это - на усмотрение компилятора/оптимизатора. Как ему удобнее. Вобщем случае он может вообще никак не инкрементироваться в теле цикла, а только в его конце. Или вообще цикл может быть развёрнут оптимизатором в линейный код. А все инкрементные и декрементные адресации заменены на адресации по указателю с фиксированным смещением. А при следующей перекомпиляции с другими исходными условиями - не развёрнут, оставлен цикл.
|
|
|
|
|
Feb 6 2018, 14:57
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(SSerge @ Feb 6 2018, 17:44)  Извольте. Стандарт С явно указывает что порядок вычисления левой и правой частей оператора присваивания не определён. А в С++ понаписали такого что и с бутылкой не разберёшь. Так что да, по крайней мере в С, никто не гарантирует что pSigRe во время вычисления правой части не окажется уже инкрементирован в результате случившегося раньше вычисления левой части оператора присваивания. Благодарствую! Хотя к чему такая толерантность. Мода А вот Кейл с --remarks на строку *pSigRe++ = log2f(*pSigRe) * 15.0515; даже не заикнулся. Буду смотреть, что он накомпилировал. Позже. Сейчас покидаю дискуссию. Цитата(jcxz @ Feb 6 2018, 17:45)  Вобщем случае он может вообще никак не инкрементироваться в теле цикла, а только в его конце. Это уж дудки. В каждой операции цикла сделает все, что приказали.
|
|
|
|
|
Feb 6 2018, 15:54
|

Местный
  
Группа: Участник
Сообщений: 492
Регистрация: 12-11-11
Пользователь №: 68 264

|
Довольно интересная тема в Си, связанная с базовым понятием точки следования. Код while (*s++ = *t++) В конце условия стоит точка следования, а тем более, переменные разные, результат будет всегда одинаковым. В конструкциях Код i = i++; нет ни одной точки следования, кроме завершающей точки с запятой, поэтому результат не определен, выполнение приводит к undefined behavior. Гуглите "sequence ponts in C". Например, тут.
|
|
|
|
|
Feb 6 2018, 16:33
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ViKo @ Feb 6 2018, 16:57)  Это уж дудки. В каждой операции цикла сделает все, что приказали. Он может даже количество итераций сделать не такое как Вы указали - например: объединить каждую чётную и нечётную итерации в одну, уменьшив их число в 2 раза. Может разбить цикл на два: в одном цикле объединить итерации попарно, в другом - выполнять по одной. И ещё много чего может. Попробуйте как-нить включить максимальную оптимизацию. Цитата(Сергей Борщ @ Feb 6 2018, 17:48)  Вас ждет еще много открытий в жизни. Посмотрите листинги своих программ повнимательнее. Я думаю, что ViKo никогда ещё не включал оптимизацию. И не заглядывал при этом в асм
|
|
|
|
|
Feb 6 2018, 16:41
|

Знающий
   
Группа: Свой
Сообщений: 584
Регистрация: 22-11-07
Из: Курская область
Пользователь №: 32 571

|
Цитата(ViKo @ Feb 6 2018, 15:34)  Имею массив из float и указатель на него. Код pSigRe = SigRe; *pSigRe++ = log2f(*pSigRe) * 15.0515; Точно, так нельзя писать?  Должно выполняться по порядку: 1. (*pSigRe) 2. log2f() 3. pSigRe++ 4. *pSigRe 5. умножение 6. присвоение. ИМХО так делать можно, компилятор не должен ругаться.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|