2012-08-27 28 views
6

Mã của tôi chứa đoạn như thế này:SBRM/RAII cho std :: va_list/va_start()/va_end sử dụng

std::va_list ap; 
    va_start(ap, msgfmt); 
    snprintf_buf buf; 
    const tchar * msg = buf.print_va_list(msgfmt, ap); 
    va_end(ap); 

Đây là ngắn và va_start()va_end() gần nhau nên họ không có nhiều của một vấn đề . Ngoại lệ từ các cuộc gọi giữa hai cuộc gọi có thể là một vấn đề (hay không?).

Thử nghiệm đơn giản cho thấy việc gọi va_start() từ một hàm không có dấu ba chấm không được phép. Đang gọi va_end() từ một chức năng khác với va_start() được gọi từ được phép hay không? Về cơ bản, tôi tò mò nếu có thể sử dụng thành ngữ SBRM/RAII cho các cuộc gọi này, ngay cả khi cần thiết phải gọi va_start() theo cách thủ công và sau đó chuyển phiên bản std::va_list vào trường hợp bảo vệ RAII/SBRM của tôi?

Trả lời

6

Thật không may, không. Các đặc điểm kỹ thuật của va_startva_end đòi hỏi rằng:

Mỗi gọi của va_startva_copy macro được kết hợp bởi một invocation tương ứng của va_end vĩ mô trong cùng chức năng.

Do đó, va_end phải nằm trong chính hàm variadic, chứ không phải là hàm hủy lớp.

+0

Trích dẫn từ đâu? – wilx

+0

@wilx: Chuẩn C99, 7.15.1/1. –

0

Một trong những triển khai có thể giả định std :: va_list = char * và va_end() chỉ cần đặt con trỏ đó là null. Nguyên nhân, nó có thể được gọi là bên ngoài chức năng. Nhưng tôi không chắc chắn, nó sẽ hoạt động tương tự trên các nền tảng khác.

Tốt hơn để bọc các chức năng này với một lớp học.

Các vấn đề liên quan