вызов alloca( ) из другого параметра вызова функции?

#linux #malloc #alloca

#linux #malloc #alloca

Вопрос:

Почему вызов alloc( ) в качестве параметра другого вызова функции, подобного этому func(x, alloca(size), z); , считается неправильным в соответствии с книгой под названием the linux programming interface

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

   void *y; 
  y = alloca(size); 
  func(x, y, z); 
  

хотя это неправильно

 func(x, alloca(size), z);  /* WRONG! */
  

разве эти 2 части не должны быть эквивалентными.Сначала alloca вызывается первый, а затем func вызывается с его возвращаемым значением, поэтому, если кто-нибудь может объяснить, как alloca выделить память в стеке, что делает оба подхода разными.

Комментарии:

1. Есть ли какие-либо причины, почему это «неправильно»? Термины «правильный» / «неправильный» субъективны. Это «неправильно» только потому, что в одной строке есть два вызова функции, которые не соответствуют некоторому стилю кода?

2. @KamilCuk это согласно книге под названием the linux programming interface собираюсь отредактировать вопрос цитатой из книги

Ответ №1:

alloca Страница руководства упоминает об этом в разделе ОШИБОК:

Во многих системах alloca() нельзя использовать внутри списка аргументов вызова функции, потому что пространство стека, зарезервированное alloca(), появится в стеке в середине пространства для аргументов функции.

Например, в func(x, alloca(1000), z); вы могли бы закончить с макетом стека, как

  sp 100c:    x
 sp 1008:    .... space reserved by alloca
 sp    8:
 sp    4:    sp 8 (return value of alloca())
 sp    0:    z
  

Общие ABI требуют, чтобы параметры func(void *, void *, void *) находились в расположениях [sp 0] , [sp 4] и [sp 8] . Ожидается макет, аналогичный

  sp 100c:    .... end of space reserved by alloca
 sp    c:    .... space reserved by alloca
 sp    8:    x
 sp    4:    sp 0x0c (return value of alloc())
 sp    0:    z
  

Комментарии:

1. Итак, это ошибка, которая будет исправлена и не имеет ничего общего с тем, как alloc( ) предполагается работать?

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

3. Вы предполагали, что стек растет снизу? Как параметры помещаются в стек (порядок, в котором они помещаются в стек)? Не могли бы вы подробно объяснить «почему»?

4. В данном примере стек растет сверху вниз, и параметры заполняются в заданном порядке (сначала x , затем alloca() , затем результат alloca() и последний z ).

5. @ensc Но я все еще не понимаю, почему макет стека плохой ( "because the stack space reserved by alloca() would appear on the stack in the middle of the space for the function arguments." ). Компилятор не смог определить местоположение параметра z из-за распределения выделенной памяти от sp 1008 до sp 8 ?