2016-02-12 22 views
11

Trong cuốn sách Hiệu quả hơn C++ (Số 15), tôi đọc mã đó trở nên chậm hơn đáng kể nếu các ngoại lệ được kích hoạt, ngay cả khi chúng không được sử dụng. Theo tôi, các trường hợp ngoại lệ bị hạn chế sử dụng và tôi cố gắng tránh chúng, nhưng đây là một chủ đề khác.Làm thế nào để tắt xử lý ngoại lệ?

tôi không hoàn toàn hiểu được tuyên bố của ông:

  1. gì cho phép/vô hiệu hóa ngoại lệ nghĩa là gì? Nó là sự khác biệt giữa việc có không hoặc nhiều hơn số không cố gắng/bắt khối? Nó là một lá cờ biên dịch? Điều gì sẽ xảy ra nếu tôi sử dụng một DLL trong đó các ngoại lệ có thể xảy ra?
  2. Giả sử không có ngoại lệ được quẳng:
    • Liệu mã trở nên chậm hơn như một toàn thể hoặc chỉ những phần mà chương trình vào/thoát thử khối/catch trở nên chậm hơn? Theo tác giả, cả hai đều đúng.
  3. Tôi làm cách nào để biên dịch mà không có ngoại lệ? Tôi có thể làm điều này ngay cả khi tôi đã thử/nắm bắt các khối không? Tôi có thể làm điều này nếu DLL tôi sử dụng có thể ném ngoại lệ?
+1

Cuốn sách cũ, trình biên dịch đã trở thành một heckofalot thông minh hơn kể từ đó. Một phong nha ngày hôm nay có thể làm điều đó với số không trên không, bằng cách sử dụng tra cứu dựa trên bảng từ địa chỉ hướng dẫn để tìm mã mà cần phải chạy khi ngăn xếp là unwound.Nhưng nếu bạn muốn băn khoăn về nó anyway sau đó xem xét thông qua các tùy chọn trình biên dịch, hầu hết có một tùy chọn để vô hiệu hóa tính năng này. –

+0

"Theo ý kiến ​​của tôi, các trường hợp ngoại lệ bị hạn chế sử dụng, và tôi cố gắng tránh chúng, nhưng đây là một chủ đề khác." Tôi đoán là mã của bạn không gọi bất kỳ cuộc gọi hệ thống nào có thể sai được. Bạn đang lập trình một CPU nóng? –

+0

@ user4590120: Ngoại lệ không phải là cách duy nhất để xử lý lỗi. Tôi sử dụng mã trả lại để kiểm tra thành công hay thất bại. – Fabian

Trả lời

6

Việc bật/tắt ngoại lệ có nghĩa là gì?

Chuyển cờ đến trình biên dịch vô hiệu hóa sự phù hợp tiêu chuẩn liên quan đến ngoại lệ và không tạo ra bất kỳ hỗ trợ ngoại lệ nào.

Điều gì sẽ xảy ra nếu tôi sử dụng DLL trong trường hợp ngoại lệ nào có thể xảy ra?

Nếu một số thư viện xử lý ngoại lệ nội bộ, không có gì. Nếu nó cho phép nó thoát khỏi người gọi (tôi không bao giờ thấy bất kỳ thư viện nào làm điều đó, vì các vấn đề ABI, nhưng bất cứ điều gì), chương trình của bạn bị treo (trong trường hợp tốt nhất) vì nó không thể xử lý nó. Nếu có một wrapper cho DLL mà mã của bạn bao gồm và chuyển đổi mã lỗi thành trường hợp ngoại lệ (thường xảy ra), thì nó giống như khi bạn sử dụng các ngoại lệ trong mã của mình.

Mã có chậm hơn hoặc không chỉ là các phần mà chương trình vào/thoát khối try/catch bị chậm hơn không? Theo tác giả, cả hai đều đúng.

Lưu ý rằng sách bạn đang trích dẫn cũ. Trình biên dịch đang phát triển. Các trình biên dịch hiện đại sử dụng các ngoại lệ không chi phí mà không phải chịu chi phí hiệu quả nếu ngoại lệ không được ném ra. Xử lý ngoại lệ làm cho thực thi lớn hơn vì nó sẽ tạo ra tất cả dữ liệu và mã cần thiết để xử lý các ngoại lệ, nhưng nó không nên làm cho nó chậm hơn trên đường dẫn không đặc biệt.

Tôi làm cách nào để biên dịch mà không có ngoại lệ? Tôi có thể làm điều này ngay cả khi tôi đã thử/nắm bắt các khối không?

Bạn làm điều đó theo cách cụ thể của trình biên dịch. Tham khảo tài liệu biên dịch của bạn. Thông thường, làm như vậy làm cho mã từ chối trình biên dịch chứa bất kỳ cơ sở nào có liên quan đến ngoại lệ, ví dụ: chỉ ra try làm số nhận dạng không được công nhận.

+1

"Xử lý ngoại lệ làm cho thực thi lớn hơn" - lớn hơn cái gì? chương trình tương đương với các giá trị trả về lỗi cũng cần mã và dữ liệu để xử lý chúng. Ưu điểm lớn của trường hợp ngoại lệ là mã xử lý lỗi và dữ liệu có thể được để lại trên đĩa ban đầu, vì vậy chương trình của bạn sẽ khởi động nhanh hơn. – MSalters

+0

"nó không nên làm cho nó chậm hơn trên con đường không đặc biệt" - trong thực tế, xử lý ngoại lệ hiện đại làm cho con đường không lỗi _faster_. Điều này là do trình biên dịch có thể xác định và tối ưu hóa đường dẫn đó. Với các giá trị trả về lỗi, trình biên dịch không biết có tối ưu hóa giá trị trả về '== 0' hoặc'! = 0' hay không, vì các hàm khác nhau sử dụng các quy ước giá trị trả về khác nhau. – MSalters

+1

@MSalters so với mã chính xác được biên dịch không hỗ trợ ngoại lệ (điều này có nghĩa là mã ban đầu phải không có xử lý ngoại lệ). Điều này loại bỏ việc xử lý ngoại lệ đối với thư viện chuẩn ('new' thường chuyển thành nothrow' new', thay thế 'bad_alloc' exception với sự cố truy cập con trỏ null sau, ví dụ) –