Вычисление выражений C++: что происходит внутри?

Я все еще изучаю С++. Я пытаюсь понять, как выполняется оценка, довольно поэтапно. Итак, используя этот простой пример, оператор выражения:

инт х = 8 * 5 - 5;

Вот что, верю, происходит. Скажите, пожалуйста, насколько я далек от цели:

  1. Операнды x, 8, 5 и 5 "вычисляются". Возможно, для хранения каждого значения создается временный объект (я не слишком в этом уверен).

  2. 8 * 5 оценивается как 40, которое хранится во временном файле.

  3. 40 (временно) - 5 оценивается как 35 (еще одно временное).

  4. 35 копируется в x.

  5. Все временные объекты уничтожаются в порядке, обратном их созданию (значение отбрасывается).

Я хотя бы близок к тому, чтобы быть правым?


person Alfred Oswald    schedule 11.09.2016    source источник
comment
С точки зрения очень высокого уровня, да. На самом деле операции выполняются в регистрах процессора. А на самом деле все выражение оценивается во время компиляции, так что все, что вы в итоге компилируете, это x=35.   -  person Sam Varshavchik    schedule 11.09.2016
comment
Позвольте мне найти вопрос, чтобы пометить его как дубликат...   -  person Jean-François Fabre    schedule 11.09.2016
comment
@SamVarshavchik Спасибо, сэр. Хм. Что произойдет, если все операнды будут именованными объектами, а не литералами? Будет ли он создавать временные файлы, так сказать, на лету, а не во время компиляции?   -  person Alfred Oswald    schedule 11.09.2016
comment
На шаге 1 левая сторона x не оценивается, так как это не операнд. Это будет операнд только для оператора быстрого доступа, такого как «+ =»   -  person milbrandt    schedule 16.07.2017


Ответы (1)


«Спасибо, сэр. Хм. Что произойдет, если все операнды будут именованными объектами, а не литералами? Будет ли это создавать временные объекты, так сказать, на лету, а не во время компиляции?»

Как упомянул Сэм, вы на правильном пути на высоком уровне. В вашем первом примере он будет использовать регистры ЦП для хранения временных объектов (поскольку они не являются именованными объектами), если они будут именованными объектами, это зависит от флагов оптимизации, установленных в компиляторе, и сложности кода относительно того, как «оптимизировано 'код будет сгенерирован. Вы можете взглянуть на разборку, чтобы действительно увидеть, что происходит. например, если вы делаете

a = 5;
b = 2;
c = a * b;

компилятор попытается сгенерировать наиболее оптимальный код, а поскольку в этом случае есть 2 константы, которые известны во время компиляции, и вы делаете умножение на 2, он сможет использовать ярлыки, иногда умножения заменяются битовыми операциями которые дешевле (умножить на 2 - это то же самое, что сдвинуть 1 влево)

именованные переменные должны где-то жить, либо в стеке, либо в куче, и ЦП будет использовать адрес именованных объектов, чтобы передавать их и выполнять над ними функции. (если они достаточно малы, он поместится в регистры и будет работать с ними, иначе он начнет использовать память, сначала кеш, а затем просочиться в ОЗУ)

Вы можете поискать в Google «абстрактное синтаксическое дерево», чтобы получить представление о том, как читаемый код С++ преобразуется в машинный код.

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

person Giel    schedule 13.08.2017