Я не могу представить, что делает компилятор, когда, например, нет значения lvalue, например: number >> 1; Моя интуиция подсказывает мне, что компилятор будет отбрасывать эту строку из компиляции из-за оптимизации, и если оптимизация будет удалена, что произойдет? Использует ли регистр для манипуляции? или он ведет себя так, как если бы это был вызов функции, поэтому параметры передавались в стек, а используемая память помечена как освобожденная? ИЛИ он преобразует это в операцию NOP? Могу ли я увидеть, что происходит с помощью отладчика VS ++? Благодарим вас за помощь.C фиктивные операции
ответ
В примере, который вы даете, он отбрасывает операцию. Он знает, что операция не имеет побочных эффектов и, следовательно, не нужно выделять код для выполнения инструкции, чтобы создать правильную программу. Если вы отключите оптимизацию, компилятор все еще может испускать код. Если вы включите оптимизацию, компилятор также может испускать код тоже - это не идеально.
Вы можете увидеть код, который компилятор испускает, используя параметр командной строки /FAsc
компилятора Microsoft. Этот параметр создает файл списка, который выводит код объекта компилятору, перемежающийся с соответствующим исходным кодом.
Вы также можете использовать «просмотр разборки» в отладчике, чтобы увидеть код, сгенерированный компилятором.
Используя «разборку разметки» или /FAsc
на оптимизированный код, я ожидаю, что не будет испускаемого кода из компилятора.
Спасибо за помощь :). Я сделал несколько экспериментов с этим на VS ++ с оптимизацией и без нее. Они дают тот же результат, когда никакая lvalue не дается ничего не делается. Нет инструкции даже для инициализации (число = 0) !!! Но что-то интересное случается так, как сказал Ник, когда это приводит к появлению некоторых других инструкций на «Разборке», начиная с шага инициализации волатильного номера int и инструкции бит-сдвига. Думаю, мне нужно глубже понять, что означает летучий. Спасибо вам за помощь. –
Предполагая, что number
является обычной переменной целочисленного типа (не volatile
), тогда любой компетентный оптимизирующий компилятор (Microsoft, Intel, GNU, IBM и т. Д.) Генерирует абсолютно НИЧЕГО. Не nop
, никакие регистры не используются и т. Д.
Если оптимизация отключена (в «сборке отладки»), тогда компилятор может «делать то, что вы просили», потому что он не понимает, что это не происходит У меня есть побочные эффекты от кода. В этом случае значение будет загружено в регистр, сдвинутый вправо один раз. Результат этого не сохраняется нигде. Компилятор выполнит «бесполезное устранение кода» в качестве одного из шагов оптимизации - я не уверен, какой из них, но для такого рода относительно простой вещи, я ожидаю, что компилятор будет разбираться с довольно базовыми настройками оптимизации. В некоторых случаях, когда речь идет о циклах и т. Д., Компилятор не может оптимизировать код, пока не будут включены более продвинутые параметры оптимизации.
Как уже упоминалось в комментариях, если переменная является энергозависимой, то считывание памяти, записанное number
, должно быть выполнено, поскольку компилятор ДОЛЖЕН читать volatile
.
В Visual Studio, если вы «просмотрите разборку», он должен показать вам код, сгенерированный компилятором.
Наконец, если это был C++, существует также вероятность того, что переменная не является обычным целым типом, функция вызывает operator>>
, когда этот код просматривается компилятором - эта функция может иметь побочные эффекты, кроме возвращения результат, поэтому вполне может быть выполнено. Но этого не может быть в C, так как нет перегрузки оператора.
Спасибо за помощь :). Я сделал несколько экспериментов с этим на VS ++ с оптимизацией и без нее. Они дают тот же результат, когда никакая lvalue не дается ничего не делается !!! 00FB101C rep stos dword ptr es: [edi] \t int number = 0, result = 0; 00FB101E mov dword ptr [число], 0 00FB1025 mov dword ptr [результат], 0 номер << 1; } 00FB102C xor eax, eax –
Так что это оптимизация, даже если у вас нет оптимизации. Это не совсем неожиданно. –
- 1. Как сгенерировать сгруппированные фиктивные переменные?
- 2. Angularjs $ HTTP фиктивные вопросы
- 3. SQL: сделать фиктивные строки
- 4. фиктивные вопросы о keystore?
- 5. Фиктивные фильтры в Django
- 6. Mule MUNIT фиктивные http.uri.params
- 7. Фиктивные объекты возвращает нуль
- 8. Eclipse, показывающий фиктивные ошибки
- 9. Фиктивные объекты без сеттера
- 10. pdev destroys Операции c/C++
- 11. C# Операции BitConverter.GetBytes в C++
- 12. C#: GridView, рядовые операции
- 13. операции побитовое | = в C
- 14. C++ Qt: побитовые операции
- 15. C# операции Путь
- 16. Основные операции C
- 17. C# код завиток операции
- 18. C Матричные операции
- 19. C#, операции Тип данных
- 20. OpenCL C++ cl_float4 операции
- 21. Арифметические операции в C++
- 22. C# операции переключения xamarin
- 23. Mongo C++ массовые операции
- 24. Путаница C++ операции умножения
- 25. Операции смены счета C#
- 26. C бит операции головоломка
- 27. C++ итераторы операции
- 28. Операции C# linq
- 29. C# интерфейс название операции
- 30. Унарные операции в C++
Почему бы вам просто не взглянуть на сгенерированную сборку? Я уверен, что компилятор просто исключит выражение. Здесь нет стандартного ответа, компилятор может делать все, что захочет, пока семантика вашей программы не изменится. –
Фактически, * если * 'number' является' volatile', компилятор ** должен тщательно протачивать и не может просто исключить выражение - чтение переменной volatile может иметь побочные эффекты. –
Nik, Можете ли вы рассказать мне, почему компилятор не должен отбрасывать чтение из изменчивого, когда инструкция, содержащая чтение, не имеет никакого побочного эффекта? Я не вижу ничего, что поддерживало бы ваше утверждение в стандарте. Есть ли какое-то предложение, на которое вы ссылаетесь? – MikeB