เรียก 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 จัดสรรหน่วยความจำบนสแต็กที่ทำให้ทั้งสองวิธีแตกต่างกันอย่างไร


person Khaled    schedule 16.09.2020    source แหล่งที่มา
comment
มีเหตุผลใดบ้างว่าทำไมมันถึงผิด? เงื่อนไขถูก/ผิดเป็นเรื่องส่วนตัว มันผิดหรือเปล่าเพียงเพราะว่ามีการเรียกใช้ฟังก์ชันสองครั้งในบรรทัดเดียวกันซึ่งไม่เป็นไปตามสไตล์โค้ดบางอย่าง   -  person KamilCuk    schedule 16.09.2020
comment
@KamilCuk เป็นไปตามหนังสือชื่อ the linux programming interface จะแก้ไขคำถามด้วยคำพูดจากหนังสือ   -  person Khaled    schedule 16.09.2020


คำตอบ (1)


หน้า alloca กล่าวถึงสิ่งนี้ในส่วน BUGS:

ในหลายระบบ ไม่สามารถใช้ 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
person ensc    schedule 16.09.2020
comment
นี่คือ BUG ที่จะได้รับการแก้ไขและไม่เกี่ยวข้องกับการทำงานของ alloc( ) หรือไม่ - person Khaled; 16.09.2020
comment
alloca ควรจะทำงานโดยขยายสแต็ก ไม่มีรายละเอียดแน่ชัดว่าสิ่งนี้จะเกิดขึ้นได้อย่างไร การใช้งานที่มีอยู่ส่วนใหญ่/ทั้งหมดประสบปัญหา (การออกแบบ) ข้อบกพร่องบางอย่าง (เช่น ปัญหาจริงหรือพฤติกรรมในกรณีข้อผิดพลาด) และฉันไม่คาดหวังว่าสิ่งเหล่านี้จะได้รับการแก้ไข คุณจะต้องระมัดระวังเมื่อ alloca() - person ensc; 16.09.2020
comment
คุณถือว่าสแต็กเติบโตจากด้านล่างหรือไม่? พารามิเตอร์ถูกผลักเข้าไปในสแต็กอย่างไร (ลำดับที่พวกมันผลักเข้าไปในสแต็ก) คุณช่วยอธิบายรายละเอียด 'ทำไม' ได้ไหม? - person jinbeom hong; 01.05.2021
comment
ในตัวอย่างที่กำหนด สแต็กขยายจากบนลงล่างและพารามิเตอร์จะถูกกรอกตามลำดับที่กำหนด (แรก x จากนั้น alloca() จากนั้นผลลัพธ์ของ alloca() และสุดท้าย z) - person ensc; 02.05.2021
comment
@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 - person jinbeom hong; 05.05.2021