Сколько примитивных шагов в y = x ++?

y=x++;

За сколько шагов он ломается на уровне компилятора без оптимизации, а не на уровне процессора или инструкций?
Создан ли какой-либо временный объект для присваивания x или y, или это происходит напрямую?

5

Решение

C ++ следует принципу «как будто», поэтому ответ на самом деле «n» шагов.

  • возможно 2: 1) назначить x в y, 2) приращение x,
  • возможно 1 если y никогда не используется
  • возможно неопределенное поведение, является y объявлен как int& y = x;
  • возможно 100 присваивания и переназначения, которые в итоге дают одинаковый результат.
15

Другие решения

  1. временная переменная создается со значением == x
  2. x увеличивается
  3. старая ценность x (хранится в этой временной переменной) присваивается y

Это будут основные шаги.

Зависит от того, что вы подразумеваете под «примитивом» — если вы имеете в виду инструкции процессора, то ответ будет другим.

Возможно, вы захотите прочитать больше об постфиксных и префиксных операторах увеличения / уменьшения.

8

Это зависит от архитектуры, для которой вы компилируете этот код.

C ++ не определяет подобные вещи или даже возможные «примитивные шаги».

Один из возможных ответов для почтенного Процессор M68000, возможно:

move.l x, d0
addq.l #1, x
move.l d0, y

Итак, для этого используются три инструкции (примитивные шаги) и одна временная в виде регистра d0,

Примечание: прошло некоторое время с тех пор, как я написал сборку M68k, я надеюсь, что приведенный выше код действителен, но, похоже, в настоящий момент возникают проблемы с получением соответствующих справочных страниц. В качестве иллюстрации, я уверен, что это действительно.

2

Зависит от того, что вы имеете в виду примитивный шаг, если примитивный шаг — это инструкции процессора, я провел быструю проверку, как показано ниже:

(среда Linux, g ++ 4.6.3)
используйте g ++ -S main.cpp, чтобы показать, какие инструкции процессора генерируются g ++, я получил вывод ниже:

movl -8(%ebp), %eax<br>
movl %eax, -4(%ebp)<br>
addl $1, -8(%ebp)

Это означает, что g ++ скопирует y в x, а затем увеличит x. В этом случае генерируются 3 инструкции процессора (если вы считаете их примитивными шагами).

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

2

Увидеть Таблица приоритетов операторов

Шаги происходят следующим образом:

  • Временная переменная назначается с xценность.

  • x увеличивается на 1.

  • y присваивается временное значение переменной.

Итак, 3 примитивных шага на абстрактном уровне.

1
  • выделить регистр для адреса х
  • адрес загрузки х
  • выделить временный регистр для х
  • разыменование х
  • выделить регистр для вас
  • назначить у<= х
  • приращение х
  • написать обратно х
  • выделить временный регистр для адреса у
  • адрес загрузки у
  • магазин у

Затем после многих этапов оптимизации он обрабатывается, возможно, двумя инструкциями:

add r0, r1, #0
add r1, r1, #1

Спасибо за комментарии — в любом случае, я хотел сказать, что компилятору может потребоваться выполнить некоторые действия, чтобы просто прочитать переменную. (является ли он глобальным или находится в фрейме локального стека или имеет абсолютный адрес, указанный в файле компоновщика …)

РЕДАКТИРОВАТЬ: конечно, это не конец истории: какие переменные х & у тебя есть? Они длиннее ширины регистра машины? Они короче и требуют расширения нуля или знака? Может быть, они плавающие или двойные и требуют вызова во внешнюю библиотеку …

0
По вопросам рекламы [email protected]