@@ -421,7 +421,7 @@ <h2 id="index-_1">前言</h2>
421
421
<blockquote>
422
422
<p><img src="../img/bulb.png" height="30px" width="auto" style="margin: 0; border: none"/> 本书还在持续更新中……要追番的话,可以在 <a href="https://github.com/parallel101/cppguidebook">GitHub</a> 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一封电子邮件,提醒你小彭老师更新了。</p>
423
423
</blockquote>
424
- <p>更新时间:2025年01月21日 12:07:30 (UTC+08:00)</p>
424
+ <p>更新时间:2025年01月21日 12:26:11 (UTC+08:00)</p>
425
425
<p><a href="https://parallel101.github.io/cppguidebook">在 GitHub Pages 浏览本书</a> | <a href="https://142857.red/book">在小彭老师自己维护的镜像上浏览本书</a></p>
426
426
<h2 id="index-_2">格式约定</h2>
427
427
<blockquote>
@@ -703,7 +703,15 @@ <h2 id="hello_world-_5">注释</h2>
703
703
</ul>
704
704
</li>
705
705
<li><a href="#platform-_13">标准库御三家</a><ul>
706
- <li><a href="#platform-_14">标准库的调试模式</a></li>
706
+ <li><a href="#platform-_14">标准库的调试模式</a><ul>
707
+ <li><a href="#platform-gcc_1">GCC 开启标准库调试模式</a></li>
708
+ <li><a href="#platform-msvc_1">MSVC 的标准库调试模式</a></li>
709
+ </ul>
710
+ </li>
711
+ <li><a href="#platform-_15">警告选项</a><ul>
712
+ <li><a href="#platform-gcc_2">GCC 建议开启的警告选项</a></li>
713
+ </ul>
714
+ </li>
707
715
<li><a href="#platform-c11-abi">C++11 ABI 问题</a></li>
708
716
</ul>
709
717
</li>
@@ -858,15 +866,58 @@ <h2 id="platform-_13">标准库御三家</h2>
858
866
<p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 牛头人笑话:“如果你不知道一个人是用的什么标准库,那么你可以猜他用的是 libstdc++。因为即使他的编译器是 Clang,他用的大概率依然是 libstdc++。”</p>
859
867
</blockquote>
860
868
<h3 id="platform-_14">标准库的调试模式</h3>
861
- <p>TODO</p>
869
+ <p>不少标准库都有提供</p>
870
+ <h4 id="platform-gcc_1">GCC 开启标准库调试模式</h4>
871
+ <p>如果你用的是 GCC 默认的 libstdc++ 库,可以定义宏 <code>#define _GLIBCXX_DEBUG</code> 以开启调试模式,此模式下会帮助检测标准库用法上出现的未定义行为,例如尝试解引用 <code>end()</code> 迭代器时,会抛出错误信息,帮助你检查代码中有没有未定义行为。</p>
872
+ <p>也可以通过命令行选项 <code>-D_GLIBCXX_DEBUG</code> 开启。</p>
873
+ <p>在 CMake 中添加以下选项,即可对特定目标程序启用标准库调试模式:</p>
874
+ <pre><code class="language-cmake">target_compile_definitions(你的程序 PRIVATE _GLIBCXX_DEBUG)
875
+ </code></pre>
876
+ <blockquote>
877
+ <p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 有的人会老老实实的复制粘贴,连“你的程序”都忘记改成你真正的程序名。</p>
878
+ </blockquote>
879
+ <p>在 CMakeLists.txt 最前面加上可以对所有接下来的目标启用:</p>
880
+ <pre><code class="language-cmake">add_compile_definitions(_GLIBCXX_DEBUG)
881
+
882
+ add_executable(你的程序1) # 示例
883
+ add_executable(你的程序2) # 示例
884
+ </code></pre>
885
+ <p>注意:</p>
886
+ <p>开启此选项后,如果你的 exe 程序链接了其他用 C++ 写的库,那么这些库也必须开启调试模式!否则 ABI 会出现不兼容,导致奔溃。这是因为 <code>_GLIBCXX_DEBUG</code> 开启后,会改变 C++ 容器的布局和大小(为了调试而塞入的额外帮手变量导致容器结构与开启前不同),链接其他用 C 语言写的库不会有问题,因为此宏仅会影响标准库中 C++ 的部分。</p>
887
+ <p>开启标准库调试模式后,因为需要做很多参数安全性检查,性能会受损,建议仅在调试环节启用!等你调试完消除了未定义行为后,在最终发布的版本中中关闭,恢复正常性能。</p>
888
+ <p>你可以通过判定 <code>CMAKE_BUILD_TYPE</code> 是否等于 <code>Debug</code>,实现只在 Debug 模式下启用标准库安全检查。</p>
889
+ <pre><code class="language-cmake">if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
890
+ add_compile_definitions(-D_GLIBCXX_DEBUG)
891
+ endif()
892
+ </code></pre>
893
+ <h4 id="platform-msvc_1">MSVC 的标准库调试模式</h4>
894
+ <p>MSVC 有两个“config”,其中 Debug config 就是标准库调试模式,会帮助你检查迭代器越界等常见未定义行为。</p>
895
+ <h3 id="platform-_15">警告选项</h3>
896
+ <h4 id="platform-gcc_2">GCC 建议开启的警告选项</h4>
897
+ <p>建议初学者开启以下选项,可以避免很多常见错误写法,改善你的代码质量:</p>
898
+ <pre><code>-Wall -Wextra -Weffc++
899
+ -Werror=uninitialized
900
+ -Werror=return-type
901
+ -Wconversion -Wsign-compare
902
+ -Werror=unused-result
903
+ -Werror=suggest-override
904
+ -Wzero-as-null-pointer-constant
905
+ -Wmissing-declarations
906
+ -Wold-style-cast -Werror=vla
907
+ -Wnon-virtual-dtor
908
+ </code></pre>
909
+ <p>视频介绍:https://www.bilibili.com/video/BV1qT421a7zj</p>
862
910
<h3 id="platform-c11-abi">C++11 ABI 问题</h3>
863
911
<p>在一些特别古老的发行版上(比如 Ubuntu 16.04、CentOS),他们的标准库不支持 C++11,可以开启这个宏:</p>
864
912
<pre><code class="language-cpp">#define _GLIBCXX_USE_CXX11_ABI 0
865
913
</code></pre>
866
914
<p>或者命令行选项 <code>-D_GLIBCXX_USE_CXX11_ABI=0</code>。</p>
867
- <blockquote>
868
- <p><img src="../img/warning.png" height="30px" width="auto" style="margin: 0; border: none"/> 为了更好的学习现代 C++,还是建议安装新的发行版。</p>
869
- </blockquote></section><section class="print-page" id="variable_types"><h1 id="variable_types-_1">变量与类型 (未完工)</h1>
915
+ <p>由于 Linux 发行版大多会捆绑特定 GCC 版本(往往是很低的版本!),为了更好的学习现代 C++,我建议:</p>
916
+ <ol>
917
+ <li>安装新的 Linux 发行版,最好是 Arch Linux,Tumbleweed 这类<strong>滚动更新</strong>的发行版,它们的所有包永久保持最新。</li>
918
+ <li>自己从源码编译 Clang,LLVM 团队打造优秀的代码品质使得 Clang 对系统底层解耦,不像 GCC 那么难伺候环境依赖。</li>
919
+ <li>或者使用 Wendous 等可以自由安装最新版 MSVC 的系统。</li>
920
+ </ol></section><section class="print-page" id="variable_types"><h1 id="variable_types-_1">变量与类型 (未完工)</h1>
870
921
<div class="toc">
871
922
<ul>
872
923
<li><a href="#variable_types-_1">变量与类型 (未完工)</a></li>
0 commit comments