- 博客(176)
- 资源 (6)
- 收藏
- 关注
原创 C/C++ 编译优化 Flags 实战指南:-O0 ~ -O3, -g~-g3
本文系统解析了C/C++编译优化标志的核心作用与最佳实践。首先强调了正确配置编译参数对代码性能、调试性和安全性的关键影响。重点分析了-O*优化级别的特性差异、-g调试信息的真实作用,以及-fno-omit-frame-pointer和-fno-common等标志的诊断价值。针对不同场景(Debug/UT/CI/Release)提供了优化组合建议,特别指出诊断能力应优先于性能优化,CI环境需比生产环境更严格。最后纠正了常见误区,提出现代编译应遵循"可回溯问题才是可维护问题"的原则。全文15
2026-01-27 17:20:40
590
原创 深入理解 C++ 的 lvalue / xvalue / prvalue 及 decltype 推导规则
摘要:本文系统解析C++11引入的三大值类别(lvalue/xvalue/prvalue),重点阐述其与decltype推导规则的关系。lvalue代表可定位对象,xvalue表示即将失效的对象,prvalue是纯计算结果。文章通过典型示例揭示decltype(auto)在工程中的危险用法,特别是括号导致的引用陷阱,并提出实用判断流程:分析表达式值类别→套用decltype规则→检查意外引用。最后强调decltype(auto)应仅用于需要保留引用语义的场景,普通函数优先使用auto或显式类型,避免返回局部
2026-01-14 10:47:20
766
原创 VS Code 内置变量与配置文件完全指南
VS Code内置变量系统提供了强大的配置灵活性,主要包括工作区、文件、环境和自定义变量,可替代硬编码路径实现跨项目复用。通过settings.json管理工作区设置和自定义配置项,配合tasks.json定义自动化任务,开发者能构建可移植的开发环境。关键点包括:1)使用${workspaceFolder}等变量替代绝对路径;2)在settings.json中定义统一配置;3)利用tasks.json实现构建、测试等任务自动化。注意变量替换支持程度取决于具体扩展实现。
2026-01-06 16:27:05
1139
原创 深入理解 Pytest 输出捕获机制:为什么你的 print 没有显示?
Pytest 默认捕获 print 输出以保持终端整洁,只在测试失败时显示捕获内容。本文深入解析了 pytest 的输出捕获机制及其设计理念,介绍了核心参数(-s、-v、-r)的功能差异,特别指出并行测试时 -s 参数会失效的问题。文章提供了不同场景下的最佳配置方案:日常开发推荐使用 -v -r a 保持输出整洁,调试时建议使用 -s -n 0 实时查看输出。同时解释了常见问题的原因,如并行模式导致 -s 失效等,帮助开发者更好地利用 pytest 进行测试。
2026-01-05 15:17:27
1055
原创 C++ 代码覆盖率分析:精准控制代码覆盖率统计的利器,GCOVR_EXCL_LINE,GCOVR_EXCL_START/GCOVR_EXCL_STOP
GCOVR_EXCL_LINE是gcovr工具的专用标记,用于从代码覆盖率统计中排除特定行或代码块。它可精准过滤防御性编程、错误处理等无需测试的代码,使覆盖率报告更准确。支持单行排除(GCOVR_EXCL_LINE)、多行排除(GCOVR_EXCL_START/STOP)和分支排除(GCOVR_EXCL_BR_LINE),兼容LCOV/GCOV标记系统。合理使用该标记能消除统计偏差,但需避免过度排除掩盖真实测试缺口。
2026-01-04 13:18:14
252
原创 GCC -fhardened 面向生产构建的安全加固落地指南
GCC 14 引入的 -fhardened 是一个面向生产环境的安全加固选项集合,目标是在不改变 ABI 的前提下,系统性启用主流 Linux 平台的编译期与链接期防护能力。本文将从工程视角出发,深入解析 -fhardened 的设计目标、与 PIE / ASLR 的关系、与 LTO 的已知问题,以及在 CMake 中的可控、可验证的最佳实践方案。本文将深入解析 -fhardened 的设计目标、与 PIE/ASLR 的关系、与 LTO 的已知问题,以及在 CMake 中的最佳实践方案。
2025-12-25 16:58:33
853
原创 C++ Lambda表达式的隐式转换陷阱
C++ Lambda表达式隐式转换陷阱分析 摘要:本文深入剖析C++ Lambda表达式在隐式转换、指针转换中的常见陷阱。重点分析了无捕获Lambda可隐式转换为函数指针的特性,及其在条件判断中始终为真的问题(编译器警告-Waddress)。通过代码示例展示了Lambda对象输出为1的原因(先转为函数指针再转为bool),以及通过+运算符和reinterpret_cast获取函数地址的正确方法。文章还对比了有/无捕获Lambda的类型差异,并给出实践建议:应明确调用Lambda而非直接转换,推荐使用std:
2025-12-12 15:07:50
799
原创 C++ inline 关键字class内部使用指南
内联函数是一种编译器优化技术,编译器会在调用点直接展开函数代码,而不是通过函数调用机制。✅ 减少函数调用开销✅ 提高执行效率⚠️ 可能增加代码体积(如果函数被多次调用)public:// ✅ 自动内联 - 不需要 inline// ✅ 自动内联// ❌ 冗余的 inlineprivate:int value_;规则: 在类定义的{}内直接实现的函数体,自动内联。inline void func() { } // 冗余场景是否需要 inline原因类内定义的成员函数。
2025-10-30 13:26:03
968
原创 测试中的 AAA 模式与 Given–When–Then 模式详解
单元测试结构化模式比较:AAA与Given-When-Then 本文对比了单元测试中两种经典结构模式:技术导向的AAA(Arrange-Act-Assert)和业务导向的Given-When-Then。AAA模式通过准备、执行、验证三阶段确保测试结构清晰,适合开发者使用;而Given-When-Then源自行为驱动开发,采用自然语言描述测试场景,更利于跨团队沟通。两者本质相同但表达方式不同,建议在C++测试实践中结合使用:以AAA为基础架构,添加Given/When/Then注释增强可读性。单元测试优先采用
2025-10-09 16:53:25
1158
原创 cmake_parse_arguments()构建清晰灵活的 CMake 函数接口
本文详细介绍了CMake中cmake_parse_arguments()函数的使用方法,它可替代手动解析参数的繁琐方式。文章从基础语法入手,通过示例代码展示了如何定义无值参数、单值参数和多值参数。该函数能自动生成带前缀的变量,支持参数任意顺序调用,提高了代码可读性和维护性。还讨论了参数分类规则、使用限制和实用技巧,如动态前缀支持。最后总结了该函数的六大优势,特别推荐用于多参数构建函数、跨平台配置等场景,是规范CMake函数接口的理想选择。
2025-07-30 17:15:15
660
原创 理解 CMake 中的 variable_watch 功能:一个实用的调试工具
本文介绍了CMake中实用的调试工具variable_watch,它能监视变量变化并触发回调函数。通过注册回调函数,开发者可以追踪变量被访问或修改的时机、位置及上下文信息(包括变量名、访问类型、当前值、文件路径和调用栈)。该功能特别适用于调试复杂CMake脚本、理解第三方模块、分析依赖关系等场景。虽然功能强大,但作者提醒该工具仅适用于调试而非生产环境,且可能产生大量输出。variable_watch为开发者提供了观察CMake内部机制的窗口,是构建系统调试的有力助手。
2025-07-22 14:18:47
673
原创 在 VSCode 中配置并使用 Clang-Format 进行 C++ 代码自动格式化
本文介绍了在VSCode中配置Clang-Format对C++代码进行自动格式化的方法。主要内容包括:1)环境准备,需安装C/C++插件、准备Clang工具和项目.clang-format文件;2)两种配置方式,通过图形界面或直接编辑settings.json文件设置格式化工具路径和规则文件;3)常见问题排查建议;4)最终实现自动格式化、支持远程开发并保持团队代码风格统一。配置完成后可提高代码整洁度,节省手动调整格式的时间。
2025-07-16 16:09:35
2262
原创 CMake Object Library:避免重复编译的优雅之道
在 CMake 项目中,当需要将同一源文件同时用于构建静态库和共享库时,传统方法会导致源文件被重复编译,浪费时间和资源。CMake 提供的 Object Library 可以解决这一问题。Object Library 是一种特殊的库,它只将源文件编译成对象文件,而不进行链接。这些对象文件可以被复用到多个其他目标中,从而避免重复编译。通过使用 Object Library,可以显著提高编译效率,减少资源浪费。具体实现方式是通过 add_library(objlib OBJECT src/lib.c) 创建 O
2025-05-20 15:43:37
806
原创 使用 Modern CMake 构建现代 C++ 项目:target从入门到实践
CMake 是 C++ 项目的主流构建系统,Modern CMake 是推荐的最佳实践。本文介绍了 Modern CMake 的核心理念,包括通过 target_* 系列命令管理依赖、清晰的目录结构设计、使用 target_sources() 管理源码、安装与导出库、以及 CMakePresets.json 的使用。Modern CMake 强调通过 target 管理一切,避免全局变量,确保依赖清晰。文章还展示了如何安装库并让下游项目通过 find_package() 引用,以及如何通过 CMakePre
2025-05-15 16:47:53
872
原创 【C++ 编译优化】为什么你应该开启 -Wall -Wextra -pedantic -Werror
让编译器当你的“代码把关人”,是写出高质量 C++ 的第一步。把警告当成错误处理,不是因为你怕错,而是因为你在意质量。
2025-05-14 16:40:18
582
原创 C++ 代码覆盖率分析:使用 CMake + Gcovr 生成 HTML/XML/JSON 报告
完整代码覆盖率流程编译:使用选项,生成.gcno文件。运行:运行测试,生成.gcda文件。分析:使用gcov解析.gcda和.gcno文件。生成报告gcovr读取gcov输出,并生成 HTML、XML、JSON 报告。通过这套方法,我们可以高效地分析 C++ 代码的测试覆盖率,并在 CI/CD 中集成代码质量检查。
2025-02-25 13:29:28
994
原创 vscode 设置在编辑器的标签页超出可视范围时自动换行(workbench.editor.wrapTabs)
workbench.editor.wrapTabs”: true 是 VS Code(Visual Studio Code) 的一个设置项,它的作用是 在编辑器的标签页超出可视范围时自动换行,而不是显示滚动条。如果同时打开多个文件,当标签页(Tab)数量过多时,它们会自动换行显示,而不是挤在一行里导致部分标签不可见。默认值:false(不开启,超出时会出现滚动条)适用于小屏幕或同时打开多个文件时提高可读性。需要修改settings.json。
2025-02-05 16:35:46
1699
原创 如何打开vscode系统用户全局配置的settings.json
settings.json 是 Visual Studio Code(VS Code) 的用户配置文件,它存储了 编辑器的个性化设置,包括界面布局、代码格式化、扩展插件、快捷键等,是用户全局配置(影响所有 VS Code 项目)settings.json 配置文件 - 适合高级用户,自定义更复杂的设置。图形界面(UI Settings) - 适合不熟悉 JSON 配置的用户。VS Code 的 settings.json。📌 settings.json 的作用。
2025-02-05 16:28:53
5908
原创 C++ Brain Teasers:重载决议最佳匹配和歧义
要调用 std::string 重载,我们需要一个用户定义的转换序列(底部),这涉及创建一个新的临时 std::string 对象。如果重载对至少一个参数具有更好的转换,并且对任何其他参数没有更差的转换,则该重载被视为最佳可行函数,并通过重载解析选择。如果存在从参数到参数类型的隐式转换,则该重载将添加到可行函数集。但是第一个重载对第一个参数的转换更好(int → int 优于 int → float),而对第二个参数的转换并不差(两个重载都是 int → int),因此它被重载解析选为最佳可行函数。
2024-12-31 17:41:40
413
原创 C++ Brain Teasers: 未指定和实现定义的行为-函数参数的求值顺序
C++ 中没有从左到右或从右到左求值的概念。任何表达式的任何部分的求值顺序(包括函数参数的求值顺序)均未指定(下面列出了一些例外情况)。编译器可以按任何顺序求值操作数和其他子表达式,并且可能在再次求值同一表达式时选择其他顺序。大多数程序都有一些未指定或实现定义的行为;与未定义的行为相反,这没什么问题。只是不同的实现在允许的行为集内可能会表现得略有不同。C++ 标准并未严格指定所有内容;它为实现留下了一些自由。这允许每个实现在特定系统上做出最好的选择。
2024-12-31 16:42:34
312
原创 链接成功但找不到符号的原因及解决方案
问题描述在链接过程中,动态库链接成功,但被其他人调用时,编译器无法找到动态库中的符号,导致编译失败。例如:可能原因静态库未正确包含在链接过程中:静态库可能没有被正确添加到链接命令中。头文件未正确包含:使用符号的代码中可能没有正确包含相关头文件。链接顺序不正确:链接顺序不正确可能导致符号未解析。我这里的动态库libmathtoolkit.so链接libGeometry.a成功,但是在提供给第三方使用时发现找不到定义,原因是静态库中的符号未被使用,链接器优化掉了这些符号解决方案强制链接静态库。
2024-12-31 10:03:12
1315
原创 CMake:打印出脚本中所有可访问的变量
CMake 提供了一个非常有用的命令:get_cmake_property,它可以动态检索 CMake 的元信息,例如变量列表、缓存变量、模块路径等。参考学习:https://stackoverflow.com/questions/9298278/cmake-print-out-all-accessible-variables-in-a-script。通过学习和应用上述方法,你可以轻松获取和操作 CMake 的元信息,编写出更加高效、健壮的构建脚本。想知道当前的 CMake 是否支持模块功能?
2024-12-03 15:51:51
870
原创 CMake 与 pkg-config 编写和集成 .pc 文件
pkg-config 是一个用于管理库的编译和链接参数的工具。它通过读取 .pc 文件(Package Config 文件)来获取库的元数据信息,如包含目录、库路径、依赖关系等。这样,开发者无需手动管理这些复杂的编译选项,简化了构建过程。编写 .pc 文件基础结构一个标准的 .pc 文件通常包含以下几个部分:变量定义:用于简化路径管理。基本信息:库的名称、描述和版本。编译和链接标志:指示如何包含和链接库。依赖关系:列出库所依赖的其他库。示例 .pc 文件。
2024-10-15 15:45:26
2356
原创 使用C++ 17 variant and visit实现 Multiple Dispatch
get_objects(): 假定这个函数返回一个 std::vector,其中包含若干 std::variant 对象,即飞船或小行星的列表。std::visit: 通过传入的两个 std::variant(obj 和 other),std::visit 会自动匹配其中包含的类型,并将其传递给 lambda 函数。对于每对 obj 和 other,使用 std::visit 来处理它们的类型并调用适当的 lambda 函数。= default;
2024-08-26 14:52:41
964
原创 Flake8 和 Autopep8 使用指南
Flake8 和 Autopep8 集成到 CI/CD 流程中,确保在代码提交和合并时自动进行检查和格式化,1.1 基本使用运行 Flake8 来检查指定目录下的代码:bash复制代码此命令将扫描 my_project 目录中的所有 Python 文件,并输出检测结果。1.2 配置Flake8 支持在多个位置进行配置,包括用户目录和项目目录中的配置文件。配置文件可以是 setup.cfg、tox.ini、.flake8 文件中的 [flake8] 段落。
2024-08-09 17:41:26
1316
原创 Flake8 与 Autopep8 兼容性指南
为了确保代码风格的一致性和自动化管理,理解这两个工具的功能差异以及它们之间的版本兼容性是非常重要的。本文将从功能区别、版本对应关系、兼容性检查方法等方面进行总结,帮助您更好地使用这两个工具。pipdeptree 是一个工具,可以帮助您查看 Python 包的依赖关系,从而确认 Flake8 和 Autopep8 使用的 pycodestyle 版本是否一致。锁定版本: 使用 pip 的 requirements.txt 文件锁定 Flake8 和 Autopep8 的版本,确保它们之间的依赖关系兼容。
2024-08-09 17:32:03
909
原创 clang-tidy 使用指南
clang-tidy 需要一个编译数据库来了解如何编译你的代码。编译数据库通常是一个名为 compile_commands.json 的文件。在这个示例中,clang-tidy 会对 test.cpp 文件进行分析,并报告任何潜在的问题。例如,它可能会警告 test 函数中的未使用变量 x。clang-tidy 是一个用于 C++ 代码的静态分析工具,可以帮助你发现代码中的潜在问题和改进点。这将在 build 目录中生成一个 compile_commands.json 文件。
2024-08-08 16:58:34
2144
1
原创 vscode显示120字符或者80字符提示线或者显示垂直标尺
一般规定一行代码不超过80或者120个字符。取决于团队的编码规范。文件-》首选项-》设置-》搜索或添加editor.rulers。vscode显示120字符或者80字符提示线或者显示垂直标尺。打开全局设置的settings.json。不同公司不同团队有不同的规定。效果,颜色可以根据需要设置。添加提示线并配置颜色。
2024-01-16 18:38:11
10504
原创 lambda中的constexpr变量
x 和 z 可以在 lambda 函数中使用而不被捕获,是因为它们具有不同的存储持续时间。x 是一个 constexpr 变量,这意味着它具有在编译时确定的常量值。另一方面,z 是一个全局变量,这意味着它具有静态存储持续时间,并且可以从程序的任何部分访问,包括在 lambda 函数内部。x 是一个 constexpr 变量,它在编译时被确定并存储在只读内存中。这是因为constexpr变量在编译期就已经被计算出来,并且它的值是在编译时确定的,所以在lambda表达式中使用它是安全的。
2023-05-08 15:05:21
382
原创 python的 __init__.py文件中使用__all__变量
显示函数的文档:在终端中运行pydoc module_name.function_name,其中module_name是包含要查看文档的函数的模块的名称,function_name是要查看文档的函数的名称。生成HTML格式的文档:在终端中运行pydoc -w module_name,其中module_name是要生成文档的模块的名称。显示模块的文档:在终端中运行pydoc module_name,其中module_name是要查看文档的模块的名称。显示pydoc的帮助:在终端中运行pydoc -h。
2023-05-05 16:45:49
2225
原创 C++ 预编译头文件(Precompiled Header,PCH)
后续编译时,如果其他源文件中也包含了同样的预编译头文件,编译器会直接使用之前生成的二进制文件,而不是重新预处理一遍头文件。它的原理是先将一些常用的头文件预处理,生成一个二进制文件(通常是.pch文件),然后在后续的编译中,直接引用这个二进制文件,避免了重复的预处理过程,从而提高了编译速度。例如,如果你预编译了“stdafx.h”头文件,你就会得到一个预编译头文件,每次你包含“stdafx.h”头文件时,编译器都会自动搜索名为“stdafx.h.gch”的预编译头文件。
2023-05-05 16:22:27
1496
原创 聚合体初始化(aggregate initialization)
总的来说,在C++17中满足如下条件之一的对象被认为是聚合体是一个数组或者是一个满足如下条件的类类型classstructunion):没有用户定义的和explicit的构造函数没有使用using声明继承的构造函数没有private和protected的非静态数据成员没有virtual函数没有的基类然而,要想使用聚合体初始化来初始化基类中没有private或者protected的成员没有private或者protected的构造函数。
2023-02-01 17:19:07
1121
原创 C++ 17 variant and visit
std::variant是C++ 17的重要新特性。它非常常用以至于不得不去学习它。它实际上是C语言中的union的拓展。它可以存储多种多样的类型,具体类型只有在运行时才能确定。你甚至可以存储自定义的类型。或者是定义一个元素都是variant的数组。这个数组里面每一个元素的类型都可以不相同!而std::visit是与之配套的访问器。通过std::visit能够不关心具体类型地写出算法,实现算法的泛用。
2022-11-17 13:12:37
860
原创 try_emplace向std::map实例中高效并有条件的插入元素
map是STL里重要容器之一。它的特性总结来讲就是:所有元素都会根据元素的键值key自动排序(也可根据自定义的仿函数进行自定义排序),其中的每个元素都是的键值对,map中不允许有键值相同的元素,因此map中元素的键值key不能修改,但是可以通过key修改与其对应的value。如果一定要修改与value对应的键值key,可将已存在的key删除掉,然后重新插入。cpp17 使用我们需要用键值对填充一个map我通常会使用insert或emplace函数对map。
2022-11-01 23:17:10
3676
原创 快速或安全的访问std::vector实例的方法, std::vector的插入排序
可能是STL容器中适用范围最广的,因为其存储数据的方式和数组一样,并且还有相对完善的配套设施。不过,非法访问一个vector实例还是十分危险的。如果一个vector实例具有100个元素,那当我们想要访问索引为123的元素时,程序就会崩溃掉。如果不崩溃,那么你就麻烦了,未定义的行为会导致一系列奇奇怪怪的错误,查都不好查。经验丰富的开发者会在访问前,对索引进行检查。这样的检查其实比较多余,因为很多人不知道有内置的检查机制。
2022-10-30 20:26:57
1102
原创 向 lambda 传递 this的拷贝
lambda里捕获了 *this,所以传递进 lambda的是一份拷贝。因此,即使在 d被销毁之后使用捕获的对象也没有。如果我们使用[this]、[=]或者 [&]捕获 this,那么新线程将会陷入未定义行为,因为当线程中打印name的。这里,捕获 *this意味着该 lambda生成的闭包将存储当前对象的一份拷贝。向 lambda 传递 this的拷贝。时候将会使用一个已经销毁的对象的成员。
2022-09-18 16:33:07
1688
C++ 代码覆盖率分析:使用 CMake + Gcovr 生成 HTML/XML/JSON 报告 源码
2025-02-25
OpenCV3.4.2-YOLOv3.7z
2020-03-04
MFC图像处理.rar
2020-01-03
第十届蓝桥杯大赛选手资源数据包(单片机)
2019-03-22
numpy matplotlib 及其依赖whl文件包
2020-02-06
dbg_amd64.rar
2020-02-06
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅