C Программирование: разница между ++ я и я = я + 1 с точки зрения ассемблера?

Это был вопрос интервью. Я сказал, что они такие же, но это было признано неверным ответом. С точки зрения ассемблера есть ли какая-то мыслимая разница? Я скомпилировал две короткие программы на C с использованием gcc-оптимизации по умолчанию и -S, чтобы увидеть выход ассемблера, и они совпадают.

Ответы

Ответ 1

Интервьюер, возможно, хотел получить ответ примерно так:

i=i+1 нужно будет загрузить значение i, добавить его к нему, а затем вернуть результат обратно в i. Напротив, ++i может просто увеличивать значение с помощью одной команды сборки, поэтому теоретически это может быть более эффективным. Однако большинство компиляторов оптимизируют разницу, и сгенерированный код будет точно таким же.

FWIW, тот факт, что вы знаете, как смотреть на сборку, делает вас лучшим программистом, чем 90% людей, с которыми мне приходилось проходить собеседование на протяжении многих лет. Примите утешение в том, что вам не придется работать с невежественным неудачником, который взял у вас интервью.

Ответ 2

Похоже, вы были правы, и они были неправы. У меня была аналогичная проблема в собеседовании, где я дал правильный ответ, который считался неправильным.

Я уверенно спорил с моим интервьюером, который явно обиделся на мою дерзость. Я не получил работу, но опять же, работая с кем-то, кто "знает все", тоже не будет желательным.

Ответ 3

Возможно, вы правы. Наивный компилятор может сделать:

++i to inc [ax]

и

i = i + 1 to add [ax], 1

но любой получувствительный компилятор просто оптимизирует добавление 1 к первой версии.

Все это предполагает, что соответствующая архитектура имеет inc и добавляет инструкции (например, x86).

Ответ 4

Чтобы защитить интервьюера, контекст - это все. Каков тип i? Мы говорим на C или С++ (или на каком-то другом C-подобном языке)? Были ли вы предоставлены:

++i;
i = i + 1;

или был ли более контекст?

Если бы меня спросили об этом, мой первый ответ был бы "я неустойчив?" Если да, то разница огромна. Если нет, разница небольшая и семантическая, но прагматически нет. Доказательством этого является различие в дереве разбора и предельный смысл генерируемых поддеревьев.

Итак, похоже, что вы прагматично правы, но семантическая/критическая сторона мысли ошибочна.

Чтобы напасть на интервьюера (без контекста), мне нужно было задаться вопросом, какова цель вопроса. Если бы я задал вопрос, я бы хотел использовать его, чтобы узнать, знает ли кандидат тонкие смысловые различия, как создать дерево синтаксического анализа, как критически мыслить и т.д. И т.д. Обычно я задаю вопрос о моих собеседниках о том, что почти каждый кандидат ошибается - и это по дизайну. На самом деле меня не волнует ответ на вопрос, Я забочусь о путешествии, которое я буду принимать с кандидатом, чтобы понять, что говорит мне гораздо больше о чем правильное/неправильное в вопросе о мелочах.

Ответ 5

В С++ это зависит, если i - это int или объект. Если это объект, он, вероятно, создаст временный экземпляр.

Ответ 6

контекст здесь главный, потому что в оптимизированной версии сборки компилятор оптимизирует я ++, если он доступен для простого [inc eax]. тогда как нечто вроде int some_int = я ++ должно было бы сохранить значение я в some_int FIRST и только затем увеличивать i.