(C++17) 未捕获异常 uncaught_exceptions

文章目录

🐾前言

从 C++11 其有 std::uncaught_exception 用于判断++当前线程++ 是否有未捕获的异常。而这个函数只是返回 bool 仅能查看是否存在未捕获异常。

因此到了 C++17 被弃用,在 C++20 中移除。C++17 引入了 int std::uncaught_exceptions() 可以获得具体的数量。

std::uncaught_exception, std::uncaught_exceptions - cppreference.com

🐾实例

🪝工具类

其实这个非常简单,最常用的就是在析构函数的时候,进行获取判断。

因此可以写这么一个工具类。当然,是选择在判断出有异常还是没异常的时候触发这个 action 还是两种状态下都注册一个,都是可以的。

cpp 复制代码
#include <exception>
#include <functional>

class ExcCatch {
private:
    const int             count = 0;
    std::function<void()> action;

public:
    ExcCatch(const std::function<void()>& action = {})
        : count(std::uncaught_exceptions()), action(action) {}

    ~ExcCatch() {
        if (count != std::uncaught_exceptions()) {
            if (action) {
                action();
            }
        }
    }
};

🪝测试

此处是用 vscode 中的 Copilot 所生成的测试代码。

简单看看使用方式就行了。

cpp 复制代码
#include <exception>
#include <functional>

class ExcCatch {
private:
    const int             count = 0;
    std::function<void()> action;

public:
    ExcCatch(const std::function<void()>& action = {})
        : count(std::uncaught_exceptions()), action(action) {}

    ~ExcCatch() {
        if (count != std::uncaught_exceptions()) {
            if (action) {
                action();
            }
        }
    }
};

#include <atomic>
#include <iostream>
#include <stdexcept>

// Helper for test output
#define ASSERT_TRUE(cond, msg)                      \
    if (!(cond)) {                                  \
        std::cout << "[FAIL] " << msg << std::endl; \
    } else {                                        \
        std::cout << "[PASS] " << msg << std::endl; \
    }
#define ASSERT_FALSE(cond, msg) ASSERT_TRUE(!(cond), msg)

// Test that ExpCatch does not call action if no exception is thrown
void test_NoException_ActionNotCalled() {
    std::atomic<bool> called{false};
    {
        ExcCatch guard([&] { called = true; });
    }
    ASSERT_FALSE(called, "NoException_ActionNotCalled");
}

// Test that ExpCatch calls action if exception is thrown
void test_Exception_ActionCalled() {
    std::atomic<bool> called{false};
    try {
        ExcCatch guard([&] { called = true; });
        throw std::runtime_error("test");
    } catch (...) {
        // Exception is caught here
    }
    ASSERT_TRUE(called, "Exception_ActionCalled");
}

// Test that ExpCatch works with empty action
void test_EmptyAction_NoCrash() {
    try {
        ExcCatch guard;
        throw std::runtime_error("test");
    } catch (...) {
        // Should not crash
    }
    std::cout << "[PASS] EmptyAction_NoCrash" << std::endl;
}

// Test that ExpCatch does not call action if exception is thrown but not caught in scope
void test_ExceptionNotCaughtInScope_ActionCalled() {
    std::atomic<bool> called{false};
    auto              test_func = [&] {
        ExcCatch guard([&] { called = true; });
        throw std::runtime_error("test");
    };
    try {
        test_func();
    } catch (...) {
        // Exception is caught here
    }
    ASSERT_TRUE(called, "ExceptionNotCaughtInScope_ActionCalled");
}

int main() {
    test_NoException_ActionNotCalled();
    test_Exception_ActionCalled();
    test_EmptyAction_NoCrash();
    test_ExceptionNotCaughtInScope_ActionCalled();
    return 0;
}

⭐END

🌟交流方式

关注我,学习更多C/C++,python,算法,软件工程,计算机知识!

⭐交流方式⭐ |C/C++|算法|设计模式|软件架构-CSDN社区
B站

👨‍💻主页:天赐细莲 bilibili

相关推荐
七夜zippoe12 分钟前
Java性能调优工具篇:JMH基准测试与Profiler(JProfiler/Async-Profiler)使用指南
java·开发语言·jprofiler·jmh·async-profiler
龙泉寺天下行走16 分钟前
MinGW-w64 工具链(GCC 编译器) 的不同构建版本的区别
c++
代码AC不AC37 分钟前
【C++】异常
c++·学习·异常
小龙报1 小时前
《嵌入式成长系列之51单片机 --- Keil5创建工程》
c语言·开发语言·c++·单片机·嵌入式硬件·51单片机·学习方法
9ilk1 小时前
【基于one-loop-per-thread的高并发服务器】--- 项目测试
运维·服务器·c++·后端·中间件
无限进步_1 小时前
【C语言】贪吃蛇游戏设计思路深度解析:从零开始理解每个模块
c语言·开发语言·c++·git·游戏·github·visual studio
听风吟丶1 小时前
Java 函数式编程深度实战:从 Lambda 到 Stream API 的工程化落地
开发语言·python
rainFFrain2 小时前
qt显示类控件--- Label
开发语言·qt
渡我白衣2 小时前
深入理解 OverlayFS:用分层的方式重新组织 Linux 文件系统
android·java·linux·运维·服务器·开发语言·人工智能
西游音月2 小时前
(6)框架搭建:Qt实战项目之主窗体快捷工具条
开发语言·qt