Đầu tiên đi vào bài viết này, Kevin có một vài ghi chú:

- SEH : C Structured Exception Handling (Các định nghĩa exception được thiết lập trước bởi M$)
- handler: exception handler.
- linked list: danh sách liên kết!

Bài viết này của Kevin chỉ có ý nghĩa nếu như bạn lập trình C/C++ trên Windows, không có bất cứ ý nghĩa nào mang tính chung cho C/C++. Sở dĩ có bài viết này vì có một số thành viên đã hỏi Kevin nhưng chưa tìm thấy sự chia sẻ ở cộng đồng C Việt. Ngoài ra, một số bạn đã thần thánh hóa SEH, nên Kevin cũng mong muốn rằng bài viết này sẽ giúp mọi người hiểu rõ hơn!


Tài liệu này được xây dựng dựa trên thông tin mà M$ cung cấp trên MSDN, các bài viết của một số chuyên gia lập trình C/C++ for Windows và những gì bản thân Kevin biết về SEH.

Sự khác nhau lớn nhất giữa Structured Exception Handling (SEH) và C++ Exception Handling là: C++ exception handling đề cập trong các kiểu dữ liệu, còn C structured exception handling chỉ đề cập với một kiểu được chỉ định là unsigned int. Có thể hiểu là, C exceptions được xác định bằng một giá trị unsigned integer với các thông tin được M$ định nghĩa sẵn trong Windows, còn C++ exceptions được xác định bằng bất cứ kiểu dữ liệu nào do lập trình viên định nghĩa.

Sự khác nhau thứ 2 đó là: C structured exception là không đồng bộ trong các exceptions xảy ra tiếp theo tới các bước của quá trình điều khiển. Còn C++ exception có cơ chế đồng bộ đầy đủ, nghĩa là các exceptions chỉ xảy ra khi chúng được quăng ra (throw).

Để hiểu rõ hơn về sự khác nhau thứ 2 này, đặc biệt là vấn đề của SEH, Kevin xin miêu tả như sau:
Khi một exception xảy ra, hệ thống sẽ bắt đầu từ handler đầu tiên danh sách SEH và đưa ra một exception ở dạng như là một câu hỏi kiểu "Có thể xảy ra tai nạn, bạn có muốn phanh không?". Tại chỗ này, handler có thể chọn đề từ chối hoặc giới hạn bằng trả về EXCEPTION_CONTINUE_SEARCH. Khi điều này xảy ra, hệ thống sẽ chuyển tới handler tiếp theo của danh sách SEH với một câu hỏi tương tự. Cứ như thế cho đến khi một handler được chọn hoặc là chuyển tới hết danh sách SEH

Như vậy các bạn cũng thấy: Lợi ích lớn nhất của SEH đó là cho handler khả năng lựa chọn sẽ làm gì với một exception mà không cần quan tâm tới các handler trước đó có exception hay không (Điều này gần như là quá đủ trong nhiều trường hợp của lập trình C/C++ for Win). Nhưng đây cũng chính là một nỗi đau lớn trong các trường hợp như:
1. Bạn muốn xây dựng một hệ thống logging cho toàn bộ chương trình của bạn (Bạn sẽ có một log khổng lồ và ngu xuẩn).
2. Bạn sử dụng một component/library khác mà bạn không có quyền điều khiển. Trong component/library đó có thiết lập SEH exception handler, mà khi gặp một exception nó hiện ra thông báo và kết thúc chương trình (Điều này là rất bình thường). Tại lúc đó, bạn sẽ không bao giờ có cơ hội để bắt được exception đó, trừ khi chỉ có duy nhất mình bạn sử dụng SEH (Có thể lúc này bạn sẽ nghĩ mình là giỏi nhất ).

Nếu C SEH xảy ra trong chương trình C++ (thiết lập ở /EHa Model), nó có thể được handle bằng một struct exception handler với bộ lọc kèm theo hoặc với một C++ catch handler, hoặc bất cứ cái nào gần với ngữ cảnh của exception đó.

SEH đã được đưa vào danh sách không khuyến cáo sử dụng kể từ khi Windows XP/2003 ra đời! Zhanli thành viên của blog MSDN cũng viết một bài khuyến cáo sử dụng C++ exception trong C++ code thay vì sử dụng C SEH. Matt Pietrek trong bài giới thiệu về Vectored Exception Handling cũng đưa ra nhận xét về SEH như Kevin đã nêu, và đưa ra sự thay thế cho SEH là VSH bắt đầu từ Windows XP/2003.

Nếu bạn thực sự quan tâm đến lập trình C/C++ for Win, hãy tìm hiểu Vectored Exception Handling bạn có được nhiều ưu thế hơn!

Cảm ơn sự quan tâm và đóng góp chia sẻ của tất cả các bạn!