va_end
được sử dụng để làm sạch. Bạn không muốn đập vỡ ngăn xếp, phải không?
Từ man va_start
:
va_end()
Mỗi gọi của va_start() phải được kết hợp bởi một invocation tương ứng của va_end() trong chức năng tương tự. Sau cuộc gọi va_end (ap) biến ap là không xác định. Nhiều traversals của danh sách, mỗi cái được bracket bởi va_start() và va_end() là có thể. va_end() có thể là macro hoặc hàm.
Lưu ý sự hiện diện của từ phải.
Ngăn xếp có thể bị hỏng vì bạn không biết số va_start()
đang làm. Các macro va_*
có nghĩa là được coi là hộp đen. Mỗi trình biên dịch trên mọi nền tảng đều có thể làm bất cứ điều gì nó muốn ở đó. Nó có thể không làm gì, hoặc nó có thể làm rất nhiều.
Một số ABI vượt qua một vài arg đầu tiên trong sổ đăng ký và phần còn lại trên ngăn xếp. A va_arg()
có thể phức tạp hơn. Bạn có thể tra cứu cách một triển khai đã cho thực hiện các vararg, điều này có thể thú vị, nhưng khi viết mã di động, bạn nên coi chúng là các hoạt động mờ đục.
Đó là một câu hỏi thực sự hay. Tôi muốn ai đó sẽ trả lời nó bằng cách mô tả một kiến trúc nơi va_end không phải là một no-op. – erikkallen
FYI: MSVS2008 - #define _crt_va_end (ap) (ap = (va_list) 0) – Yarik
@erikkallen: Thực hiện tìm kiếm google cho "define va_end" và bạn sẽ tìm thấy một số định nghĩa bất thường có thể hoặc có thể không thực chất là không op. – PlasmaHH