c / c ++ передача аргумента по указателю / аргументу по структуре кадра стека ссылок - PullRequest
2 голосов
/ 08 января 2010

Будет ли компилятор генерировать одинаковый код для обоих этих операторов?

foo1(int* val){(*val)++;}

foo2(int &val){val++;}

Будет ли он просто записывать указатель на часть параметров стека foo? Или, во втором случае, будут ли кадры стека вызывающих и foos каким-либо образом перекрываться, так что локальная переменная вызывающего абонента занимает ту же память в стеке, что и параметр для foo?

Ответы [ 4 ]

4 голосов
/ 08 января 2010

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

2 голосов
/ 08 января 2010

Это зависит.

Код, сгенерированный для обоих, будет эквивалентен, если не идентичен на большинстве платформ, если скомпилирован в библиотеку.

Любой хороший компилятор встроит такую ​​маленькую функцию, поэтому вполне возможно, что вместо того, чтобы получать адрес чего-либо в стеке, увеличивая указанное значение, он вместо этого будет увеличивать значение напрямую. Кадр стека любой встроенной функции встроен в кадр стека вызывающей стороны, поэтому в этом случае он будет перекрываться.

0 голосов
/ 27 июня 2013

относительно перекрытия стековых фреймов. Я нашел следующую информацию здесь :

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

Так что в вашем случае, если только переменные в локальных областях функций вызывающей стороны передаются перекрывающему элементу foo2,возможно!

0 голосов
/ 08 января 2010

Стеки не могут перекрываться.

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

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

...