我認爲該函數完成後會從堆棧中刪除參數,但printf等函數在調用堆棧時會從堆棧中刪除可變數量的參數。參數在變量參數函數中如何傳遞到堆棧上?
它如何知道從堆棧中刪除多少個參數?是否有一個祕密參數來指定傳遞了多少個參數?
感謝
我認爲該函數完成後會從堆棧中刪除參數,但printf等函數在調用堆棧時會從堆棧中刪除可變數量的參數。參數在變量參數函數中如何傳遞到堆棧上?
它如何知道從堆棧中刪除多少個參數?是否有一個祕密參數來指定傳遞了多少個參數?
感謝
的C調用約定指定在主叫而不是被叫一個從堆棧彈出參數負責。這就是爲什麼具有可變參數列表的函數必須是cdecl
。所以,
我認爲該函數完成後,從堆棧中刪除參數。
這僅適用於某些調用約定,對於C調用約定並非如此。
它如何知道從堆棧中刪除多少個參數?是否有一個祕密參數來指定傳遞了多少個參數?
它沒有,也沒有沒有祕密的論據。
調用者函數將清理堆棧(使用正確的調用約定)。編譯器將爲此生成代碼。編譯器確切地知道你在參數列表上傳遞了多少個參數,因爲它編譯了它..
調用代碼清理了堆棧,並且由被調用的函數來正確地確定那裏是「足夠」的論據已經通過了無論它想做什麼。這並不一定是一個說法是這樣的,它可能是這樣的:
int sum(int first, ...)
{
int s = first;
int v;
va_list va;
va_start(va, first);
while (v = va_arg(va, int) != -1)
{
sum += v;
}
va_end(va);
return sum;
}
x = sum(1, 2, 3, -1);
y = sum(1, 2, 3, 4, 5, 6, 7, 8, 9, -1);
是否意味着可變參數的函數必須有一些爭論,確定參數的個數來被訪問(如printf中的格式字符串)? –
@dhgfdg dgdfgds:無法知道已經傳遞了多少個參數,所以是_variable參數list_幾乎總是需要指定其內容的另一個參數。 –
沒有「C調用約定」這樣的東西。任何能夠以與抽象機匹配的方式滿足可觀察函數調用行爲的需求的調用約定是可行的實現。 –