@@ -421,7 +421,7 @@ <h2 id="index-_1">前言</h2>
421421<blockquote>
422422<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>
423423</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>
425425<p><a href="https://parallel101.github.io/cppguidebook">在 GitHub Pages 浏览本书</a> | <a href="https://142857.red/book">在小彭老师自己维护的镜像上浏览本书</a></p>
426426<h2 id="index-_2">格式约定</h2>
427427<blockquote>
@@ -703,7 +703,15 @@ <h2 id="hello_world-_5">注释</h2>
703703</ul>
704704</li>
705705<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>
707715<li><a href="#platform-c11-abi">C++11 ABI 问题</a></li>
708716</ul>
709717</li>
@@ -858,15 +866,58 @@ <h2 id="platform-_13">标准库御三家</h2>
858866<p><img src="../img/awesomeface.png" height="30px" width="auto" style="margin: 0; border: none"/> 牛头人笑话:“如果你不知道一个人是用的什么标准库,那么你可以猜他用的是 libstdc++。因为即使他的编译器是 Clang,他用的大概率依然是 libstdc++。”</p>
859867</blockquote>
860868<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>
862910<h3 id="platform-c11-abi">C++11 ABI 问题</h3>
863911<p>在一些特别古老的发行版上(比如 Ubuntu 16.04、CentOS),他们的标准库不支持 C++11,可以开启这个宏:</p>
864912<pre><code class="language-cpp">#define _GLIBCXX_USE_CXX11_ABI 0
865913</code></pre>
866914<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>
870921<div class="toc">
871922<ul>
872923<li><a href="#variable_types-_1">变量与类型 (未完工)</a></li>
0 commit comments