2011-01-01 31 views
20

Bạn có thể đưa ra danh sách dấu đầu dòng về sự khác biệt/ngụ ý thực tế không? Tôi đọc bài viết MSDN có liên quan, nhưng sự hiểu biết của tôi không đồng bộ trường hợp ngoại lệ vẫn còn một chút mờ.EHsc vc EHa (xử lý ngoại lệ không đồng bộ và không đồng bộ)

Tôi viết một bộ kiểm tra sử dụng Boost.Test và trình biên dịch của tôi phát ra một cảnh báo rằng EHA nên được kích hoạt:

cảnh báo C4535: gọi _set_se_translator() yêu cầu/EHA

Dự án bản thân sử dụng chỉ ngoại lệ đơn giản (từ STL) và không cần chuyển đổi/EHa. Tôi có phải biên dịch lại nó bằng/EHa để làm cho bộ kiểm thử hoạt động đúng không? Cảm giác của tôi là tôi cần/EHa chỉ cho bộ đồ thử nghiệm.

Trả lời

30

Khi bạn sử dụng/EHsc, trình biên dịch sẽ chỉ phát ra mã cho bộ lọc ngoại lệ khi nó có thể phát hiện mã được bao bọc trong khối try {} có thể ném một ngoại lệ C++. Một bộ lọc ngoại lệ đảm bảo rằng destructor của bất kỳ đối tượng C++ cục bộ nào được gọi khi stack được bỏ trong khi xử lý một ngoại lệ. Nó làm cho RAII hoạt động.

Đó là tối ưu hóa, không gian và thời gian cho mã x86, không gian cho mã x64. Không gian vì nó có thể bỏ qua mã bộ lọc ngoại lệ, đó là btw khiêm tốn. Thời gian vì trên x86 nó có thể tránh đăng ký bộ lọc ngoại lệ khi nhập khối try {}. Rất khiêm tốn btw. x64 sử dụng một cách khác để tìm các bộ lọc ngoại lệ, nó dựa trên bảng.

Cụm từ khóa trong đoạn đầu tiên là "có thể ném ngoại lệ C++". Trên Windows có các nguồn ngoại lệ khác. Giống như "a" trong/EHa, ngoại lệ không đồng bộ được nâng lên bởi phần cứng. Những thứ như ngoại lệ dấu chấm động, chia cho số không và ngoại lệ vi phạm truy cập toàn quyền. Nhưng cũng đáng chú ý là loại ngoại lệ được nêu lên bằng mã mà bạn có thể xen vào. Giống như mã được quản lý, về cơ bản mọi thứ chạy trong máy ảo.

Khi bạn muốn đảm bảo an toàn cho các đối tượng của mình đối với các loại ngoại lệ này, bạn sẽ cần sử dụng/EHa, thông báo cho trình biên dịch là luôn ghi đăng ký bộ lọc ngoại lệ.

Cảnh giác với một tác dụng phụ khó chịu của/EHa, nó làm cho việc bắt (...) nuốt tất cả ngoại lệ. Bao gồm cả những thứ bạn không bao giờ nên bắt, như AV và SO. Hãy xem __try/__except và _set_se_translator() nếu điều đó quan trọng đối với bạn.

+2

+1 Ồ, tôi không biết sự khác biệt giữa x86 và x64. Bạn có thể đề nghị bất kỳ tài liệu tham khảo về lập trình x64? Một cái gì đó như "10 phút giới thiệu về lập trình x64 cho lập trình x86" :) – 9dan

6

Vâng, nếu không có/EHa bạn không thể bắt được ngoại lệ không mong muốn để chương trình thử nghiệm của bạn sẽ thoát bất thường.

Nếu thử nghiệm có thể được thực hiện để thoát bất thường, tốt hơn là không nên vật lộn với/EHa.

Hơn nữa, việc thay đổi tùy chọn thành/EHa có nhiều tác dụng phụ bao gồm tăng kích thước thực thi và giảm hiệu suất ít. Thay đổi hiệu quả hành vi gốc.

Để sử dụng hoặc không sử dụng/EHa là một quyết định lớn thường được thực hiện ở giai đoạn thiết kế chương trình.

IMHO, các vấn đề ở văn bản viết thử nghiệm là không đáng kể để thay đổi quyết định này.

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