2010-12-10 35 views
14

Nếu tôi đang tạo một dự án mới trong C++ không được quản lý, Visual Studio 2008 hoặc cao hơn, tôi muốn sử dụng mô hình xử lý ngoại lệ nào?Visual C++ Mã không được quản lý: Sử dụng/EHa hoặc/EHsc cho ngoại lệ C++?

Tôi hiểu rằng tùy chọn/EHa dẫn đến mã kém hiệu quả hơn và cũng nắm bắt được ngoại lệ SEH, phải không?

Vì vậy, tôi đã được chỉ đạo rõ ràng tùy chọn đó và thường đi với/EHsc, do đó tôi chỉ bắt C++ ngoại lệ thực sự ném và không bắt vi phạm truy cập và execptions có cấu trúc khác, trong catch (...) xử lý. Nếu có một sự vi phạm truy cập trong mã của tôi, tôi không muốn nó bị che bởi một catch (...) {}.

Tôi mã với những người khác muốn bắt (...) {} để không làm gì và thậm chí họ muốn nó làm điều đó nếu có vi phạm truy cập, điều đó có vẻ như là một ý tưởng tồi với tôi. Nếu có lỗi do mã hóa xấu, bạn không muốn dính ngón tay vào tai và lớn tiếng nói "La la la la la!" để bạn không phải bị lỗi chương trình? Trong thực tế, nếu mã đang ở trạng thái xấu vì lỗi mã hóa, bạn có thực sự muốn mã tiếp tục không? Vì vậy, suy nghĩ chung của tôi là/EHa tạo mã lớn hơn/chậm hơn và nó cho phép các lập trình viên lấy đi mã viết rằng nếu có lỗi nghiêm trọng, nó sẽ tiếp tục chạy trong trạng thái không xác định.

BTW, tôi đang nói về các ứng dụng và mã dịch vụ là những gì chúng tôi đang viết cho hầu hết các phần. Không phải trình điều khiển thiết bị cấp thấp hoặc bất cứ thứ gì tương tự.

Hãy cân nhắc suy nghĩ của bạn.

Trả lời

16

/EHa thực hiện hai việc. Đầu tiên và quan trọng nhất, nó ngăn chặn một tối ưu hóa bỏ qua các bộ lọc ngoại lệ tự động gọi các destructors của các biến lớp cục bộ nếu trình phân tích mã không thể thấy bất kỳ mã nào có thể ném một ngoại lệ C++. Điều này làm cho ngăn xếp unwinding an toàn cho bất kỳ loại ngoại lệ, không chỉ là một ngoại lệ C + +. Chi phí cho các bộ lọc ngoại lệ này là thời gian trên x86 và không gian trên cả x86 và x64.

Và có, nó làm thay đổi hành vi của catch (...), nó bây giờ cũng lọc bất kỳ ngoại lệ SEH, không chỉ C++. Điều này thực sự là một canh bạc bởi vì bạn nắm bắt tất cả những thứ thực sự khó chịu, ngoại lệ phần cứng không đồng bộ. Mặc dù cá nhân tôi không nghĩ rằng việc bắt tất cả ngoại lệ C++ cũng rất dễ bảo vệ, bạn vẫn có một ý tưởng mơ hồ về mức độ mà trạng thái chương trình bị đột biến và tại sao nó thất bại.

Thực tế, bạn cần phải chuyển sang sử dụng __try/__except để bạn có thể viết bộ lọc ngoại lệ của riêng mình và tránh bắt các bộ lọc xấu. Mã ngoại lệ cho ngoại lệ C++ là 0xe04d5343 ("MSC"). Sử dụng _set_se_translator() sẽ là một cách tiếp cận khác.

4

Tôi sử dụng/EHa vì nó an toàn với .NET interop, trong khi/EHsc có thể không có; xem ví dụ Destructors not called when native (C++) exception propagates to CLR component.

Tuy nhiên, nếu cho một bit cụ thể của mã hiệu suất bổ sung thực sự quan trọng và bạn không cần. NET (hoặc bất cứ điều gì khác) khả năng tương thích, sau đó chắc chắn,/EHsc âm thanh tốt.

Không/EHsc cũng như/EHa không gặp phải hầu hết các lỗi bộ nhớ, vì vậy việc sử dụng các lỗi này để bắt vi phạm truy cập là trường hợp vô vọng.

+2

Bạn không bao giờ nên cố gắng bắt vi phạm quyền truy cập trong mọi trường hợp. –

+1

Đó là sự hiểu biết của tôi ... nhưng tôi có người viết bắt (...) {} và nếu/EHa được chọn, thì điều đó sẽ chôn vùi vi phạm truy cập tôi tin. Đó là một điều cần nắm bắt (...) {cleanup_stuff; ném; } nhưng ngay cả trong trường hợp đó, nếu đó là một sự vi phạm truy cập đang bị bắt, bạn có chắc là cleanup_stuff sẽ thực hiện công việc của nó không? Bạn đang ở trong trạng thái xấu, vì vậy tôi có thể nghĩ rằng chương trình là tốt nhất chỉ cần đâm ở đó. – MarkS

+3

Tôi đang làm việc trên một hệ thống máy khách/máy chủ nếu máy chủ có ngoại lệ (lý tưởng, ngoại lệ, bao gồm vi phạm truy cập), tôi muốn gửi thông báo ngoại lệ tới máy khách trước khi cho phép luồng máy chủ bị lỗi. Nếu không, máy chủ chỉ dừng đáp ứng. –

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