# VERSION_NOTES — 概念/版本验证记录(任务 1) 本文件记录 wiki 课程代码中「与语言版本相关」的论断:原文说法 → 当前 C17/C++17 是否仍成立 → 不成立则在何版本成立 → 已编译验证的结果。 验证工具:`tools/std_probe.py`(逐 `-std=` 编译,报告 pass/fail/warning)。 对照演示:`tools/demo_versions/`(每个论断一个最小可编译片段)。 > 基线:本仓库按 **C17 / C++17** 构建所有示例(见顶层 `CMakeLists.txt`)。 > 验证编译器:宿主机 `gcc/g++ 13.3.0`(原生支持 C89…C23、C++98…C++23)。 ## 验证方法 ```bash # 单片段跨版本探测(pedantic-errors 让已废除特性硬失败,便于对比) tools/std_probe.py --lang c --file tools/demo_versions/kr_implicit_int.c \ --standards c89,c99,c11,c17 --pedantic-errors tools/std_probe.py --lang c++ --file tools/demo_versions/dynamic_exception_spec.cpp \ --standards c++11,c++14,c++17,c++20 ``` --- ## 1. K&R 隐式 int(函数/参数省略类型) | | C89 | C99 | C11 | C17 | |---|---|---|---|---| | 结果 | ✅ PASS(仅警告) | ❌ FAIL | ❌ FAIL | ❌ FAIL | - **原文论断**(块 `58954439:14`「3.4 C++中所有的变量和函数都必须有类型」): C89 允许 `fun1(i){...}`(隐式 int 返回 + 隐式 int 参数)。 - **C17 是否成立**:否。C99 起废除隐式 int;C17 下非法(错误)。 - **在何版本成立**:C89(及更早)。 - **本仓库处理**:Part1 该块用 `exact_fix` 给出 C17 等价的显式类型版本 (`int fun1(int i)`);原始 C89 形式保留在 `tools/demo_versions/kr_implicit_int.c`, 供跨版本对比。 - **已编译验证**:`std_probe` 显示 c89 PASS、c99/c11/c17 FAIL(`--pedantic-errors`)。 ## 2. 三目运算符作为左值 | | C89 | C99 | C17 | C++11 | C++17 | |---|---|---|---|---|---| | 结果 | ❌ FAIL | ❌ FAIL | ❌ FAIL | ✅ PASS | ✅ PASS | - **原文论断**(块 `58954439:18`「3.8 三目运算符功能增强」): C 中三目返回右值;C++ 中三目返回两操作数公共类型的引用(可作左值)。 - **C17/C++17 是否成立**:C++ 独有特性,C++17 成立;C(含 C17)不允许。 - **本仓库处理**:该特性为 C/C++ 差异演示,保留在 `tools/demo_versions/ternary_lvalue.cpp`。 - **已编译验证**:C++ 全版本 PASS;C 全版本 FAIL(`lvalue required as left operand`)。 ## 3. `char* p = malloc(n)` 不显式转换 | | C89 | C17 | C++17 | |---|---|---|---| | 结果 | ✅ PASS | ✅ PASS | ❌ FAIL | - **原文论断**(块 `58954439:15`):C 中 `void*` 隐式转任意指针合法;C++ 必须显式转换。 - **C17/C++17 是否成立**:C 合法,C++ 非法(`invalid conversion from void* to char*`)。 - **本仓库处理**:保留在 `tools/demo_versions/malloc_no_cast.c`。 - **已编译验证**:C PASS;C++ FAIL。 ## 4. 枚举变量直接赋整型值 | | C17 | C++17 | |---|---|---| | 结果 | ✅ PASS | ❌ FAIL | - **原文论断**(块 `58954439:15` 类型严格性对照): C 中 `enum Color c = 1;` 合法(int 隐式转 enum);C++ 需显式转换。 - **C17/C++17 是否成立**:C 合法,C++ 非法(`invalid conversion from int to Color`)。 - **本仓库处理**:保留在 `tools/demo_versions/enum_assign_int.c`。 - **已编译验证**:C PASS;C++ FAIL。 ## 5. 经指针改写 const 变量 | | C89 | C17 | C++17 | |---|---|---|---| | 编译 | ✅ PASS | ✅ PASS | ✅ PASS | - **原文论断**(块 `58954439:21`「3.8/C/C++ const 异同」): 通过 `(int*)&const_var` 强转改写 const 变量,C 多见改写生效,C++ 常因 常量折叠仍读出原值。 - **C17/C++17 是否成立**:两者都能编译,但均属**未定义行为(UB)**; 「观察到的值」随编译器优化级别而变,不保证。教学价值在于说明 UB 不可依赖。 - **本仓库处理**:保留在 `tools/demo_versions/const_via_pointer.c`,注释强调 UB。 - **已编译验证**:C/C++ 均编译通过(行为属 UB,不作为「支持/不支持」结论)。 ## 6. 动态异常规范 `throw(类型...)` / `throw()` | | C++11 | C++14 | C++17 | C++20 | |---|---|---|---|---| | 结果 | ⚠️ PASS(弃用警告) | ⚠️ PASS(弃用警告) | ❌ FAIL | ❌ FAIL | - **原文论断**(块 `58954474:4`「7.2.4 异常接口声明」): 演示 `throw(int,char,char*)` 与 `throw()` 异常规范。 - **C++17 是否成立**:否。动态异常规范在 C++11 弃用、**C++17 移除**,C++17 下是语法错误。 `throw()` 的等价物是 `noexcept`;带类型列表的动态规范在现代 C++ 中无法表达。 - **本仓库处理**:Part1 该块用 `exact_fix` 改写为 `noexcept` / `noexcept(false)` 并注释说明;原始动态规范形式保留在 `tools/demo_versions/dynamic_exception_spec.cpp`(在 `-std=c++14` 下可编译)。 - **已编译验证**:C++11/14 PASS(弃用警告),C++17/C++20 FAIL。 --- ## 附:其它「平台相关」修正(非版本概念,记录于此) - **`system("pause")`**(多块):仅 Windows 可用。`common_fix` 统一改为便携 `pause()` 壳函数(读一行 stdin 等回车),Linux 可编译运行,行为一致。 - **Qt 过时 API**(Part3,Qt5.14 仍可用,保留并标注): - `QMouseEvent::x()/y()`(Qt6 建议用 `position()`); - `QString::sprintf`(Qt6 弃用); - Qt4 `SIGNAL/SLOT` 字符串写法(vs Qt5 函数指针); - `static_cast` 重载解析(`QOverload<>::of` 是 Qt5.7+ 的现代等价)。 这些保留原写法以匹配 Qt 5.14 课程环境,相关说明见 `docs/ERRATA_part3.md`。