Перейти к содержанию
    

Нет. Не понимаю каким боком относится приведённый пример к Вашему вопросу.

Пример никак к теме не относится.

Но судя по высказываниям - ожидается большая дискуссия между гуру программирования.

Начинающие начинают попкорн готовить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пример никак к теме не относится.

Но судя по высказываниям - ожидается большая дискуссия между гуру программирования.

Начинающие начинают попкорн готовить.

Так, жду-с.

Вот здесь чего-то пишут, но не могу понять.

http://en.cppreference.com/w/cpp/language/eval_order

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, жду-с.
Вам уже дали правильный и исчерпывающий ответ:

а может всё-таки сначала инкрементируете, потом считаете логарифм уже от следующего элемента, но результат записываете на место предыдущего?
Компилятор имеет на это полное право. Чего еще вы ожидаете услышать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вам уже дали правильный и исчерпывающий ответ:

Компилятор имеет на это полное право. Чего еще вы ожидаете услышать?

Здесь тоже сначала инкрементируют, потом записывают?

while (*s++ = *t++)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Точно, так нельзя писать? :w00t:

Я бы избегал подобных неоднозначностей. Лучше записать код длинне на пару строк, но так, чтобы его понял любой компилятор/транслятор/синтезатор и статический анализатор. А самое главное - вы сами через пару-тройку лет, или другой коллега))))

 

Кстати, свои произведения проверяю также CppCheck и встроенным в IAR анализатором. Иногда помогает устранить весьма абсурдные и детские ошибки, допущенные по невнимательности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь тоже сначала инкрементируют, потом записывают?

while (*s++ = *t++)

Здесь у Вас два разных указателя. А значит - нет неопределённости по операциям постинкремента.

Если конечно у Вас в неких "первых строках", которые Вы не посчитали нужным привести здесь, не записано:

#define t s

:biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь тоже сначала инкрементируют, потом записывают?

while (*s++ = *t++)

Здесь всё в порядке, т.к. справа и слева от оператора присвоения у вас разные переменные, и они не зависят от друг друга.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так, жду-с.

Извольте.

Стандарт С явно указывает что порядок вычисления левой и правой частей оператора присваивания не определён.

6.5.16 Assignment operators:

4. The order of evaluation of the operands is unspecified.

А в С++ понаписали такого что и с бутылкой не разберёшь.

 

Так что да, по крайней мере в С, никто не гарантирует что pSigRe во время вычисления правой части не окажется уже инкрементирован в результате случившегося раньше вычисления левой части оператора присваивания.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ладно. Значит, нужно найти точное толкование, когда инкрементируется указатель, если он используется справа и слева от оператора присваивания.

Это - на усмотрение компилятора/оптимизатора. Как ему удобнее.

Вобщем случае он может вообще никак не инкрементироваться в теле цикла, а только в его конце.

Или вообще цикл может быть развёрнут оптимизатором в линейный код. А все инкрементные и декрементные адресации заменены на адресации по указателю с фиксированным смещением.

А при следующей перекомпиляции с другими исходными условиями - не развёрнут, оставлен цикл.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Первый пример я бы записал так:

  for (uint32_t i = FFT_N; i--; ) {
    VarType_t result = log2f(*pSigRe) * 15.0515;
    *pSigRe++ = result;
  }

Ну для красоты result можно за цикл вынести, чтобы при каждой итерации не вызывать её конструктор (инициализатор).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извольте.

Стандарт С явно указывает что порядок вычисления левой и правой частей оператора присваивания не определён.

А в С++ понаписали такого что и с бутылкой не разберёшь.

Так что да, по крайней мере в С, никто не гарантирует что pSigRe во время вычисления правой части не окажется уже инкрементирован в результате случившегося раньше вычисления левой части оператора присваивания.

Благодарствую! Хотя к чему такая толерантность. Мода :laughing:

А вот Кейл с --remarks на строку

*pSigRe++ = log2f(*pSigRe) * 15.0515;

даже не заикнулся.

 

Буду смотреть, что он накомпилировал. Позже. Сейчас покидаю дискуссию.

 

Вобщем случае он может вообще никак не инкрементироваться в теле цикла, а только в его конце.

Это уж дудки. В каждой операции цикла сделает все, что приказали.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Довольно интересная тема в Си, связанная с базовым понятием точки следования.

while (*s++ = *t++)

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

В конструкциях

i = i++;

нет ни одной точки следования, кроме завершающей точки с запятой, поэтому результат не определен, выполнение приводит к undefined behavior.

 

Гуглите "sequence ponts in C". Например, тут.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это уж дудки. В каждой операции цикла сделает все, что приказали.

Он может даже количество итераций сделать не такое как Вы указали - например: объединить каждую чётную и нечётную итерации в одну, уменьшив их число в 2 раза. Может разбить цикл на два: в одном цикле объединить итерации попарно, в другом - выполнять по одной.

И ещё много чего может. Попробуйте как-нить включить максимальную оптимизацию.

 

Вас ждет еще много открытий в жизни. Посмотрите листинги своих программ повнимательнее.

Я думаю, что ViKo никогда ещё не включал оптимизацию. И не заглядывал при этом в асм :biggrin:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имею массив из float и указатель на него.

 

  pSigRe = SigRe;
    *pSigRe++ = log2f(*pSigRe) * 15.0515;

Точно, так нельзя писать? :w00t:

Должно выполняться по порядку:

1. (*pSigRe)

2. log2f()

3. pSigRe++

4. *pSigRe

5. умножение

6. присвоение.

ИМХО так делать можно, компилятор не должен ругаться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...