XCode与Borland环境下C++异常失效求助:如何捕获除零错误?
Hey there! I totally get how frustrating it is when try/catch blocks don’t behave as expected—especially after digging through all the related answers and hitting a wall. Let’s break down why your current setup isn’t working and how to fix it.
Why Try/Catch Isn’t Catching Division-by-Zero by Default
First, a key point: C++ doesn’t define division-by-zero as a standard exception-throwing event. It’s classified as undefined behavior, which means compilers like Clang (used in Xcode) and Borland’s C++ toolchain don’t automatically throw an exception when you divide by zero. Instead, they might crash the program, return a garbage value, or trigger a system-level signal (like SIGFPE on Unix-like systems) depending on the platform and compiler settings.
Reliable Solutions to Handle Division-by-Zero
1. Manual Divisor Check (Cross-Platform & Standard)
The most robust, portable way is to explicitly check if the divisor is zero before performing the division, then throw a standard or custom exception yourself. This works across all C++ compilers, including Xcode and Borland.
Here’s a code example:
#include <stdexcept> #include <iostream> int main() { int numerator = 10; int denominator = 0; try { if (denominator == 0) { // Throw a standard runtime error throw std::runtime_error("Division by zero attempted"); } int result = numerator / denominator; std::cout << "Result: " << result << std::endl; } catch (const std::runtime_error& e) { // Catch and handle the exception std::cerr << "Error: " << e.what() << std::endl; } return 0; }
2. Compiler/Platform-Specific Exception Handling
If you absolutely need to rely on compiler-level exception handling (not recommended for portability), here’s how to do it for your environments:
For Borland C++
Borland’s compiler has options to enable floating-point exceptions. You can use the _controlfp function to set up exception masks, then catch the exception using Borland-specific __try/__except extensions:
#include <float.h> #include <iostream> int main() { // Enable division-by-zero exceptions for floating-point operations _controlfp(_EM_ZERODIVIDE, _MCW_EM); __try { double numerator = 10.0; double denominator = 0.0; double result = numerator / denominator; std::cout << "Result: " << result << std::endl; } __except (GetExceptionCode() == EXCEPTION_FLT_DIVIDE_BY_ZERO) { std::cerr << "Caught division-by-zero exception (Borland-specific)" << std::endl; } return 0; }
Note: This only works for floating-point division, not integer division.
For Xcode (Clang/GCC)
On macOS/Xcode, division-by-zero triggers a SIGFPE signal. You can handle this using signal handlers and setjmp/longjmp to recover:
#include <csignal> #include <iostream> #include <csetjmp> jmp_buf error_buffer; void sigfpe_handler(int signal) { std::cerr << "Caught division-by-zero signal (SIGFPE)" << std::endl; longjmp(error_buffer, 1); // Jump back to the setjmp point } int main() { // Register the signal handler signal(SIGFPE, sigfpe_handler); // Set a jump point to recover from the signal if (setjmp(error_buffer) == 0) { int numerator = 10; int denominator = 0; int result = numerator / denominator; std::cout << "Result: " << result << std::endl; } return 0; }
This approach is platform-specific and can be tricky to use safely (especially in multi-threaded code), so stick to manual checks whenever possible.
Final Recommendation
Always prefer the manual divisor check—it’s compliant with the C++ standard, works across all compilers, and avoids the pitfalls of platform-specific hacks. The other methods are only useful if you’re dealing with legacy code or have specific constraints that prevent manual checks.
内容的提问来源于stack exchange,提问作者SaAd

