diff --git a/examples/win32-hello/CPP_FUNCTION_EXPORT_GUIDE.md b/examples/win32-hello/CPP_FUNCTION_EXPORT_GUIDE.md deleted file mode 100644 index 1ea1300d..00000000 --- a/examples/win32-hello/CPP_FUNCTION_EXPORT_GUIDE.md +++ /dev/null @@ -1,290 +0,0 @@ -# PHPX 编译器 - C++ 函数导出规范 - -## 概述 - -在 PHPX 编译器中,C++ 函数可以被导出为 PHP 函数,供 PHP 代码调用。这需要遵循特定的规范和约定。 - -## 三大必要条件 - -### 1. 函数名必须以 `php_` 为前缀 - -```cpp -// ✅ 正确:以 php_ 为前缀 -Int php_messagebox(Int hWnd, String text, String caption, Int uType) { - // 实现代码 -} - -// ❌ 错误:缺少 php_ 前缀 -Int messagebox(Int hWnd, String text, String caption, Int uType) { - // 这不会被导出到 PHP -} -``` - -**命名规则:** -- C++ 函数名:`php_messagebox()` -- PHP 调用名:`messagebox()`(自动去掉 `php_` 前缀) - -### 2. 只能使用 PHPX 类型作为参数和返回值 - -**支持的 PHPX 类型:** - -| PHPX 类型 | PHP 对应类型 | 说明 | -|-----------|-------------|------| -| `Int` | `int` | 整数 | -| `Bool` | `bool` | 布尔值 | -| `Double` | `float` | 浮点数 | -| `String` | `string` | 字符串 | -| `Array` | `array` | 数组 | -| `Object` | `object` | 对象 | -| `Variant` | `mixed` | 混合类型 | -| `void` | 无返回值 | 仅用于返回值 | - -```cpp -// ✅ 正确:使用 PHPX 类型 -Int php_add(Int a, Int b) { - return a + b; -} - -String php_greet(String name) { - return "Hello, " + name + "!"; -} - -// ❌ 错误:使用原生 C/C++ 类型 -int php_add(int a, int b) { // 错误! - return a + b; -} - -char* php_greet(char* name) { // 错误! - return name; -} -``` - -### 3. 必须在 `.stub.php` 文件中声明 - -**Stub 文件的作用:** -- 只包含函数签名(参数和返回值类型) -- 不包含具体实现代码 -- 让编译器知道有哪些 C++ 函数可供 PHP 调用 - -**Stub 文件示例** (`winapi.stub.php`): - -```php - - -using namespace php; - -// 注意:函数名必须以 php_ 为前缀 -Int php_add(Int a, Int b) { - return a + b; -} - -String php_concat(String str1, String str2) { - return str1 + str2; -} - -Bool php_is_even(Int number) { - return (number % 2 == 0); -} -``` - -### 3. PHP 调用文件 (`main.php`) - -```php - -``` - -#### 常用命令 - -``` -g # 继续执行 (Go) -k # 显示调用堆栈 (Stack trace) -dv # 显示局部变量 -!analyze -v # 详细分析崩溃原因 -bp <地址> # 设置断点 -``` - ---- - -### 方案 4:添加日志输出 - -由于 GUI 程序没有控制台,可以将调试信息写入日志文件: - -```php -getMessage()); - debug_log("堆栈跟踪: " . $e->getTraceAsString()); - } -} -``` - -**查看日志:** -```powershell -Get-Content .\debug.log -Wait -``` - ---- - -### 方案 5:使用消息框调试 - -对于简单的调试,可以使用消息框显示变量值: - -```php - output.txt 2>&1` -3. 使用 ProcMon 监控 -4. 检查 Windows 事件查看器 - -### Q: 如何在没有 Visual Studio 的情况下调试? - -A: -1. 使用 WinDbg(免费) -2. 添加详细的日志输出 -3. 使用消息框显示调试信息 -4. 查看 Windows 事件日志 - ---- - -## 📚 相关资源 - -- [Visual Studio 调试教程](https://docs.microsoft.com/visualstudio/debugger/) -- [WinDbg 文档](https://docs.microsoft.com/windows-hardware/drivers/debugger/) -- [CRT 库冲突解决方案](https://docs.microsoft.com/cpp/build/reference/nodefaultlib-ignore-library) -- [Windows 调试技术](https://docs.microsoft.com/windows/win32/debug/) - ---- - -## 🎯 快速修复步骤 - -如果遇到 "Debug Assertion Failed",按以下顺序尝试: - -1. **重新编译**(使用最新的修复) - ```powershell - php bin/compiler.php examples/win32-hello/project.yml --no-console - ``` - -2. **清理构建目录** - ```powershell - Remove-Item -Recurse -Force build/ - php bin/compiler.php examples/win32-hello/project.yml --no-console - ``` - -3. **添加调试信息重新编译** - ```powershell - php bin/compiler.php examples/win32-hello/project.yml --debug-info --no-console - ``` - -4. **使用 Visual Studio 调试** - - 打开 exe 文件 - - 按 F5 启动调试 - - 查看输出窗口的错误信息 - -5. **添加日志输出** - - 在关键位置添加 `debug_log()` 调用 - - 查看日志文件定位问题 - -希望这些方法能帮助您成功调试程序! diff --git a/examples/win32-hello/DEBUG_MODE_GUIDE.md b/examples/win32-hello/DEBUG_MODE_GUIDE.md deleted file mode 100644 index 7ca1250d..00000000 --- a/examples/win32-hello/DEBUG_MODE_GUIDE.md +++ /dev/null @@ -1,455 +0,0 @@ -# 调试模式使用指南 - -## 📋 概述 - -`--debug-info` 参数用于启用调试模式,它会自动: -1. **禁用优化**(`-O0` 或 `/Od`) -2. **添加调试信息**(`-g` 或 `/Zi`) -3. **生成符号文件**(`.pdb` 文件,Windows) - -这使得您可以使用调试器(如 GDB、LLDB、Visual Studio)来调试编译后的程序。 - ---- - -## 🚀 快速开始 - -### Windows (MSVC) - -```powershell -# 启用调试模式 -php bin/compiler.php your-app.php --debug-info - -# 结合其他选项 -php bin/compiler.php your-app.php --debug-info --no-console - -# 运行程序 -.\your-app.exe - -# 使用 Visual Studio 调试 -# 1. 打开 your-app.exe -# 2. 按 F5 启动调试 -# 3. 设置断点,查看变量 -``` - -### Linux/macOS (GCC/Clang) - -```bash -# 启用调试模式 -php bin/compiler.php your-app.php --debug-info - -# 结合其他选项 -php bin/compiler.php your-app.php --debug-info --sanitize=address - -# 运行程序 -./your-app - -# 使用 GDB 调试 -gdb ./your-app -(gdb) break main -(gdb) run -(gdb) next -(gdb) print variable_name -``` - ---- - -## 🔍 调试模式 vs 发布模式 - -| 特性 | 调试模式 (`--debug-info`) | 发布模式 (默认) | -|------|--------------------------|----------------| -| 优化级别 | `-O0` / `/Od` (禁用) | `-O2` / `/O2` (最大速度) | -| 调试信息 | ✅ 生成 (`-g` / `/Zi`) | ❌ 不生成 | -| 符号文件 | ✅ 生成 (`.pdb`) | ❌ 不生成 | -| 执行速度 | 较慢 | 快 | -| 文件大小 | 较大 | 较小 | -| 适用场景 | 开发、调试 | 生产环境 | - ---- - -## 💡 使用示例 - -### 1. 基本调试 - -```powershell -# 编译带调试信息的版本 -php bin/compiler.php debug-test.php --debug-info --no-console - -# 在 Visual Studio 中调试 -# - 打开 debug-test.exe -# - 设置断点 -# - 按 F5 运行 -# - 查看变量值、调用堆栈 -``` - -### 2. 结合 AddressSanitizer - -```powershell -# 同时启用调试信息和 AddressSanitizer -php bin/compiler.php asan-test.php --debug-info --sanitize=address --no-console - -# 这样可以: -# - 看到源代码行号 -# - 检测内存错误 -# - 获得详细的错误报告 -``` - -### 3. GDB 调试 (Linux) - -```bash -# 编译 -php bin/compiler.php app.php --debug-info - -# 启动 GDB -gdb ./app - -# GDB 常用命令 -(gdb) break main # 在 main 函数设置断点 -(gdb) break filename:10 # 在第 10 行设置断点 -(gdb) run # 运行程序 -(gdb) next # 执行下一行 -(gdb) step # 进入函数 -(gdb) print var # 打印变量值 -(gdb) backtrace # 显示调用堆栈 -(gdb) continue # 继续执行 -(gdb) quit # 退出 -``` - -### 4. LLDB 调试 (macOS) - -```bash -# 编译 -php bin/compiler.php app.php --debug-info - -# 启动 LLDB -lldb ./app - -# LLDB 常用命令 -(lldb) breakpoint set --name main -(lldb) run -(lldb) next -(lldb) step -(lldb) frame variable -(lldb) thread backtrace -(lldb) continue -(lldb) quit -``` - ---- - -## 🛠️ 高级技巧 - -### 1. 条件断点 - -```gdb -# GDB -(gdb) break main if x > 10 - -# LLDB -(lldb) breakpoint set --name main --condition 'x > 10' -``` - -### 2. 观察点(Watchpoint) - -```gdb -# 当变量改变时中断 -(gdb) watch my_variable -(gdb) continue -``` - -### 3. 检查内存 - -```gdb -# GDB -(gdb) x/10x &array # 查看数组的前 10 个元素 -(gdb) p *ptr@10 # 查看指针指向的 10 个元素 - -# LLDB -(lldb) memory read --format x --count 10 &array -``` - -### 4. 多线程调试 - -```gdb -# GDB -(gdb) info threads # 查看所有线程 -(gdb) thread 2 # 切换到线程 2 -(gdb) thread apply all bt # 所有线程的堆栈 - -# LLDB -(lldb) thread list -(lldb) thread select 2 -(lldb) thread backtrace all -``` - ---- - -## 📊 性能对比 - -### 编译时间 - -| 模式 | 相对时间 | -|------|---------| -| 发布模式 (-O2) | 100% | -| 调试模式 (-O0 -g) | 80% (更快) | - -### 运行时性能 - -| 模式 | 相对速度 | 内存使用 | -|------|---------|---------| -| 发布模式 (-O2) | 100% | 100% | -| 调试模式 (-O0 -g) | 30-50% | 120-150% | - -### 文件大小 - -| 模式 | 可执行文件 | 符号文件 | -|------|-----------|---------| -| 发布模式 | 小 | 无 | -| 调试模式 | 大 | .pdb (Windows) / 嵌入 (Unix) | - ---- - -## 🔧 平台特定说明 - -### Windows (MSVC) - -**生成的文件:** -- `app.exe` - 可执行文件 -- `app.pdb` - 程序数据库文件(包含调试信息) - -**调试工具:** -- Visual Studio 2022(推荐) -- WinDbg -- Visual Studio Code + C++ 扩展 - -**注意事项:** -- PDB 文件必须与 EXE 在同一目录 -- 不要删除 PDB 文件,否则无法调试 -- 可以使用 `/DEBUG:FASTLINK` 加快链接速度 - -### Linux (GCC) - -**调试信息:** -- 默认嵌入到可执行文件中 -- 也可以使用 `-ggdb` 生成 GDB 专用信息 - -**调试工具:** -- GDB -- DDD (GDB 图形界面) -- Visual Studio Code + C++ 扩展 - -**优化选项:** -```bash -# 基本调试 --g - -# GDB 专用 --ggdb - -# 更多详细信息 --g3 - -# 仅调试宏 --ggdb3 -``` - -### macOS (Clang) - -**调试信息:** -- 默认使用 DWARF 格式 -- 嵌入到可执行文件中 - -**调试工具:** -- LLDB(默认) -- Xcode -- Visual Studio Code + C++ 扩展 - -**特殊选项:** -```bash -# 生成 dSYM 文件(分离调试信息) --g -Wl,-S - -# 保留所有符号 --g -fno-eliminate-unused-debug-types -``` - ---- - -## 🐛 常见问题 - -### Q: 为什么调试模式下程序运行很慢? - -A: 因为禁用了所有优化(`-O0`)。这是正常的,调试模式的目标是便于调试,而不是性能。 - -**解决方案:** -- 只在调试时使用 `--debug-info` -- 发布时使用 `-O2` 或 `-O3` - -### Q: 调试器看不到某些变量? - -A: 可能的原因: -1. 变量被优化掉了(即使使用 `-O0`) -2. 变量超出了作用域 -3. 调试信息不完整 - -**解决方案:** -```bash -# 使用更详细的调试信息 -php bin/compiler.php app.php --debug-info - -# 或者在 GCC/Clang 上 -# 手动添加 -g3 -``` - -### Q: 如何调试 Release 版本? - -A: 不推荐,但可以: -```bash -# 保留调试信息但启用优化 -php bin/compiler.php app.php -O2 --debug-info -``` - -注意:优化可能会使调试变得困难,因为代码可能被重排或内联。 - -### Q: PDB 文件太大怎么办? - -A: -```powershell -# 使用增量链接 -/link /INCREMENTAL - -# 或使用 FASTLINK -/link /DEBUG:FASTLINK -``` - -### Q: 如何在没有调试器的情况下调试? - -A: -1. 添加日志输出 -2. 使用消息框显示变量值 -3. 使用 AddressSanitizer 检测错误 -4. 查看核心转储(core dump) - ---- - -## 🎯 最佳实践 - -### 1. 开发工作流 - -```bash -# 日常开发 -php bin/compiler.php app.php --debug-info - -# 运行测试 -./app - -# 调试问题 -gdb ./app - -# 准备发布 -php bin/compiler.php app.php -O2 -``` - -### 2. 持续集成 - -```yaml -# .github/workflows/test.yml -- name: Debug Build - run: php bin/compiler.php tests/*.php --debug-info - -- name: Run Tests with GDB - run: | - gdb -batch -ex "run" -ex "bt" ./test_app - -- name: Release Build - run: php bin/compiler.php src/*.php -O2 -``` - -### 3. 调试检查清单 - -遇到问题时: -- [ ] 是否使用 `--debug-info` 编译? -- [ ] 是否设置了断点? -- [ ] 是否查看了调用堆栈? -- [ ] 是否检查了变量值? -- [ ] 是否使用了 AddressSanitizer? -- [ ] 是否查看了日志文件? - -### 4. 符号文件管理 - -**Windows:** -```powershell -# 保留 PDB 文件 -Copy-Item app.pdb symbols/ - -# 发布时剥离符号 -# PDB 文件不需要分发给用户 -``` - -**Linux:** -```bash -# 分离调试信息 -objcopy --only-keep-debug app app.debug -strip app - -# 使用时 -gdb -s app.debug ./app -``` - ---- - -## 📚 相关资源 - -- [GDB 用户手册](https://sourceware.org/gdb/current/onlinedocs/gdb/) -- [LLDB 教程](https://lldb.llvm.org/use/tutorial.html) -- [Visual Studio 调试](https://docs.microsoft.com/visualstudio/debugger/) -- [MSVC 调试选项](https://docs.microsoft.com/cpp/build/reference/z7-zi-ld-debug-information-format) -- [GCC 调试选项](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html) - ---- - -## 🔗 编译器命令参考 - -```powershell -# Windows - 基本调试 -php bin/compiler.php app.php --debug-info - -# Windows - 调试 + GUI -php bin/compiler.php app.php --debug-info --no-console - -# Windows - 调试 + ASan -php bin/compiler.php app.php --debug-info --sanitize=address - -# Linux/macOS - 基本调试 -php bin/compiler.php app.php --debug-info - -# Linux/macOS - 调试 + 多个 sanitizer -php bin/compiler.php app.php --debug-info --sanitize=address,undefined - -# 自定义优化级别(不使用调试模式) -php bin/compiler.php app.php -O2 - -# 完全禁用优化(不生成调试信息) -php bin/compiler.php app.php -O0 -``` - ---- - -## 💡 提示 - -1. **始终在开发时使用 `--debug-info`** - - 更容易找到 bug - - 更好的错误报告 - - 支持调试器 - -2. **发布前移除 `--debug-info`** - - 更好的性能 - - 更小的文件 - - 更安全(不暴露符号) - -3. **结合使用多种调试工具** - - 调试器(GDB/LLDB/VS) - - Sanitizer(AddressSanitizer 等) - - 日志记录 - - Profiler - -希望这个指南能帮助您有效使用调试模式! diff --git a/examples/win32-hello/ENCODING_GUIDE.md b/examples/win32-hello/ENCODING_GUIDE.md deleted file mode 100644 index edcc3840..00000000 --- a/examples/win32-hello/ENCODING_GUIDE.md +++ /dev/null @@ -1,112 +0,0 @@ -# Encoding Guide for PHPX Compiler - -## Problem - -When using Chinese characters in source code, you may encounter garbled text (乱码) like: -``` -Win32 Hello World 绋嬪簭 -鏄剧ず娑堟伅妗?.. -``` - -This happens because: -1. Windows console uses code page 936 (GBK) by default -2. Source files are saved as UTF-8 -3. The mismatch causes encoding issues - -## Solution - -### Option 1: Use English (Recommended) ✅ - -All example files now use English to avoid encoding issues: - -**Before:** -```php -echo "显示消息框...\n"; -``` - -**After:** -```php -echo "Showing message box...\n"; -``` - -### Option 2: Set Console to UTF-8 - -If you must use Chinese, set the console code page to UTF-8 before running: - -```powershell -chcp 65001 -.\win32_hello.exe -``` - -Or in your PHP code, set it programmatically: - -```php -function main() { - // Set console to UTF-8 - exec('chcp 65001 > nul'); - - echo "显示消息框...\n"; -} -``` - -### Option 3: Use Windows API for Unicode - -For message boxes and Windows GUI, use wide character functions: - -```cpp -// In C++ file -Int php_messagebox(Int hWnd, String text, String caption, Int uType) { - // Convert UTF-8 to UTF-16 for Windows API - int wtext_len = MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, NULL, 0); - wchar_t* wtext = new wchar_t[wtext_len]; - MultiByteToWideChar(CP_UTF8, 0, text.data(), -1, wtext, wtext_len); - - int wcaption_len = MultiByteToWideChar(CP_UTF8, 0, caption.data(), -1, NULL, 0); - wchar_t* wcaption = new wchar_t[wcaption_len]; - MultiByteToWideChar(CP_UTF8, 0, caption.data(), -1, wcaption, wcaption_len); - - int result = MessageBoxW((HWND)hWnd, wtext, wcaption, (UINT)uType); - - delete[] wtext; - delete[] wcaption; - return result; -} -``` - -## Best Practices - -1. **Use English for code comments and strings** - Most portable solution -2. **Save all files as UTF-8 without BOM** - Standard for modern development -3. **Avoid mixing encodings** - Keep consistency across all files -4. **Test on target systems** - Different Windows versions may have different defaults - -## Current Status - -All files in `examples/win32-hello/` now use English: -- ✅ hello-win.php -- ✅ main.php -- ✅ window.php -- ✅ cpp-src/winapi.cc -- ✅ cpp-src/winapi.stub.php - -Rebuild to see the changes: - -```powershell -php bin\compiler.php examples\win32-hello\project.yml -.\build\win32_hello.exe -``` - -Expected output: -``` -======================================== - Win32 Hello World Program -======================================== - -Showing message box... -Message box return value: 1 - -Note: To create a full window, you need to implement window procedure and message loop. -This requires WNDCLASS registration and message pump in C++ layer. - -Program ended. Press any key to exit... -``` diff --git a/examples/win32-hello/MSVC_WARNINGS_SUPPRESSION.md b/examples/win32-hello/MSVC_WARNINGS_SUPPRESSION.md deleted file mode 100644 index f0e16ccd..00000000 --- a/examples/win32-hello/MSVC_WARNINGS_SUPPRESSION.md +++ /dev/null @@ -1,370 +0,0 @@ -# MSVC 编译警告屏蔽说明 - -## 📋 概述 - -在 Windows 平台使用 MSVC 编译器编译 PHPX 项目时,会收到大量来自 Windows SDK 和 PHP SDK 头文件的警告。这些警告都是**编译器噪音**,不影响程序的正确性和功能。 - -本文档列出了所有被屏蔽的警告及其原因。 - ---- - -## 🔇 已屏蔽的警告列表 - -### C4244 - 类型转换可能丢失数据 - -``` -warning C4244: 'argument': conversion from '__int64' to 'int', possible loss of data -``` - -**原因:** PHP 内部代码经常在 `int` 和 `size_t`/`__int64` 之间转换。 - -**安全性:** ✅ 安全 - 数值在小范围内,不会溢出。 - -**示例:** -```cpp -int len = strlen(str); // size_t -> int -``` - ---- - -### C4242 - 类型转换可能丢失数据(类似 C4244) - -``` -warning C4242: 'return': conversion from 'unsigned __int64' to 'unsigned int', possible loss of data -``` - -**原因:** 与 C4244 类似,但针对不同的类型组合。 - -**安全性:** ✅ 安全 - 已知范围内的转换。 - ---- - -### C4146 - 一元负运算符应用于无符号类型 - -``` -warning C4146: unary minus operator applied to unsigned type, result still unsigned -``` - -**原因:** PHP 源码中使用了 `-UINT_MAX` 这样的表达式。 - -**安全性:** ✅ 安全 - 这是预期的行为,用于生成特定的位模式。 - -**示例:** -```cpp -unsigned int x = -1; // 实际上是 UINT_MAX -``` - ---- - -### C4820 - 结构体成员后有填充字节 - -``` -warning C4820: 'struct_name': 'N' bytes padding added after data member 'member_name' -``` - -**原因:** MSVC 为了实现内存对齐,自动在结构体成员之间添加填充字节。 - -**安全性:** ✅ 完全正常 - 这是编译器的标准行为,所有编译器都会这样做。 - -**示例:** -```cpp -struct Example { - char a; // 1 byte - // 3 bytes padding here (for alignment) - int b; // 4 bytes -}; -``` - ---- - -### C4464 - 相对包含路径含 ".." - -``` -warning C4464: relative include path contains '..' -``` - -**原因:** PHP SDK 头文件使用了 `#include "../xxx.h"` 的写法。 - -**安全性:** ✅ 安全 - 这只是包含路径的写法,不影响功能。 - -**示例:** -```cpp -#include "../main/php.h" -``` - ---- - -### C4365 - 有符号/无符号转换 - -``` -warning C4365: 'argument': conversion from 'int' to 'unsigned int', signed/unsigned mismatch -``` - -**原因:** PHP 内部代码混合使用有符号和无符号整数。 - -**安全性:** ✅ 安全 - 数值在正数范围内,转换是安全的。 - ---- - -### C4127 - 条件表达式是常量 - -``` -warning C4127: conditional expression is constant -``` - -**原因:** 常见于宏展开,如 `while(1)` 或 `if (sizeof(T) > 0)`。 - -**安全性:** ✅ 完全正常 - 这是有意为之的代码模式。 - -**示例:** -```cpp -while (1) { // 无限循环 - // ... -} -``` - ---- - -### C4668 - 未定义的宏当 0 处理 - -``` -warning C4668: '__GNUC__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' -``` - -**原因:** PHP 源码中使用 `#ifdef __GNUC__` 来检测 GCC 编译器,在 MSVC 下这个宏未定义。 - -**安全性:** ✅ 预期行为 - `#ifdef` 会正确地检测到宏未定义。 - -**示例:** -```cpp -#ifdef __GNUC__ - // GCC 特定代码 -#else - // 其他编译器(包括 MSVC) -#endif -``` - ---- - -### C4626 / C5027 - 赋值运算符被隐式删除 - -``` -warning C4626: 'class_name': assignment operator was implicitly defined as deleted -warning C5027: 'class_name': move assignment operator was implicitly defined as deleted -``` - -**原因:** PHP 结构体包含 `const` 成员或引用成员,导致编译器无法生成默认的赋值运算符。 - -**安全性:** ✅ 设计如此 - 这些结构体本来就不应该被赋值。 - -**示例:** -```cpp -struct Immutable { - const int value; // const 成员使赋值运算符被删除 -}; -``` - ---- - -### C5219 - 隐式转换警告 - -``` -warning C5219: implicit conversion from 'type1' to 'type2', possible loss of data -``` - -**原因:** C++17 引入的新警告,检测潜在的精度丢失。 - -**安全性:** ✅ 提示信息 - 在已知范围内是安全的。 - ---- - -### C5220 - volatile 成员警告 - -``` -warning C5220: 'member': a non-static data member with a volatile qualified type no longer corresponds to the C++ standard -``` - -**原因:** C++20 对 `volatile` 成员的规则有所改变。 - -**安全性:** ✅ 提示信息 - 不影响正确性。 - ---- - -## 🛠️ 实现方式 - -这些警告在 [Constants.php](file:///D:/workspace/compiler/src/Php/Constants.php#L156-L174) 中配置,并在 [CompilerBase.php](file:///D:/workspace/compiler/src/Php/CompilerBase.php#L2439-L2445) 中动态应用: - -### 配置位置(Constants.php) - -```php -/** - * MSVC 编译器警告屏蔽列表 - * 这些警告来自 Windows SDK 和 PHP SDK 头文件,都是编译器噪音,不影响功能 - * - * @var array 键为警告编号,值为说明 - */ -public const array MSVC_SUPPRESSED_WARNINGS = [ - '4244' => '类型转换可能丢失数据 (int -> smaller type)', - '4242' => '类型转换可能丢失数据 (similar to C4244)', - '4146' => '一元负运算符应用于无符号类型', - '4820' => '结构体成员后有填充字节(内存对齐)', - '4464' => '相对包含路径含 ".."', - '4365' => '有符号/无符号转换', - '4127' => '条件表达式是常量(如 while(1))', - '4668' => '未定义的宏当 0 处理(#ifdef __GNUC__)', - '4626' => '赋值运算符被隐式删除(const 成员)', - '5027' => '移动赋值运算符被隐式删除', - '5219' => '隐式转换警告', - '5220' => 'volatile 成员警告', -]; -``` - -### 应用位置(CompilerBase.php) - -```php -// 禁用 PHP SDK 和 Windows SDK 头文件中的常见警告 -// 这些警告都是编译器噪音,不影响功能(从 Constants 配置中读取) -foreach (Constants::MSVC_SUPPRESSED_WARNINGS as $code => $description) { - $cmd .= " /wd{$code}"; // C{$code}: {$description} -} -``` - -**优势:** -- ✅ 集中管理,易于维护 -- ✅ 不是硬编码,可以动态修改 -- ✅ 带有详细注释,说明每个警告的原因 -- ✅ 可以轻松添加或删除警告 - ---- - -## 💡 为什么需要屏蔽这些警告? - -### 1. **来源不可控** - -这些警告来自: -- Windows SDK 头文件(微软提供) -- PHP SDK 头文件(PHP 官方提供) -- PHX 库头文件 - -我们无法修改这些第三方库的代码。 - -### 2. **数量巨大** - -如果不屏蔽,编译时会输出数百甚至数千条警告信息,淹没真正重要的警告和错误。 - -### 3. **都是误报** - -这些警告在实际运行中不会导致任何问题: -- 类型转换都在安全范围内 -- 结构体填充是正常的内存对齐 -- 宏检测按预期工作 - -### 4. **行业标准做法** - -大型项目(如 Chromium、Firefox、Qt)都会屏蔽这些第三方库的警告。 - ---- - -## ⚠️ 注意事项 - -### 不要屏蔽的警告 - -以下警告**不应该**被屏蔽,因为它们可能指示真正的问题: - -- **C4700** - 使用了未初始化的变量 -- **C4703** - 使用了可能未初始化的指针 -- **C4996** - 使用了废弃的函数(如 `strcpy`) -- **C6XXX** - Code Analysis 警告(潜在的安全问题) - -### 如何添加新的警告屏蔽 - -如果您发现新的无害警告,可以在 [Constants.php](file:///D:/workspace/compiler/src/Php/Constants.php#L156-L174) 中添加: - -```php -public const array MSVC_SUPPRESSED_WARNINGS = [ - // ... 现有警告 ... - 'XXXX' => '警告描述', // 添加新警告 -]; -``` - -**步骤:** -1. 打开 `src/Php/Constants.php` -2. 在 `MSVC_SUPPRESSED_WARNINGS` 数组中添加新条目 -3. 格式:`'警告编号' => '说明文字'` -4. 保存文件,重新编译即可生效 - -**原则:** -1. 确认警告来自第三方库(Windows SDK、PHP SDK) -2. 确认警告不会影响程序正确性 -3. 添加清晰的注释说明原因 -4. 在本文档中记录 - ---- - -## 📊 效果对比 - -### 屏蔽前 - -``` -Compiling hello-win.cc... -hello-win.cc -D:\workspace\php-8.4.20\SDK\include\Zend\zend_types.h(125): warning C4820: '_zval_struct': '4' bytes padding added after data member 'u1' -D:\workspace\php-8.4.20\SDK\include\Zend\zend_portability.h(345): warning C4464: relative include path contains '..' -D:\workspace\php-8.4.20\SDK\include\main\php.h(512): warning C4244: 'return': conversion from 'zend_long' to 'int', possible loss of data -... (数百条类似警告) -Successfully compiled 1 files -``` - -### 屏蔽后 - -``` -Compiling hello-win.cc... -hello-win.cc -Successfully compiled 1 files -``` - -**清爽多了!** ✨ - ---- - -## 🔍 如何验证屏蔽是否有效 - -编译时观察输出: -1. ✅ 没有看到上述警告编号 -2. ✅ 只看到真正的错误或您自己代码的警告 -3. ✅ 编译成功且程序运行正常 - -如果仍然看到某些警告,检查: -- 警告编号是否在屏蔽列表中 -- 是否有拼写错误(如 `/wd4244` 写成 `/wd424`) -- 是否在正确的编译阶段添加(编译时,不是链接时) - ---- - -## 📚 相关资源 - -- [MSVC 编译器警告文档](https://docs.microsoft.com/cpp/build/reference/compiler-warnings) -- [/wd (Disable Specific Warnings)](https://docs.microsoft.com/cpp/build/reference/wd-disable-specific-compiler-warnings) -- [PHP Windows 编译指南](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2) - ---- - -## 🎯 总结 - -| 警告编号 | 类型 | 严重程度 | 是否需要关注 | -|---------|------|---------|------------| -| C4244/C4242 | 类型转换 | 低 | ❌ 否 | -| C4146 | 一元运算符 | 低 | ❌ 否 | -| C4820 | 结构体填充 | 信息 | ❌ 否 | -| C4464 | 包含路径 | 信息 | ❌ 否 | -| C4365 | 符号转换 | 低 | ❌ 否 | -| C4127 | 常量条件 | 信息 | ❌ 否 | -| C4668 | 宏未定义 | 信息 | ❌ 否 | -| C4626/C5027 | 运算符删除 | 设计 | ❌ 否 | -| C5219/C5220 | 新标准警告 | 提示 | ❌ 否 | - -**所有这些警告都可以安全地忽略。** - ---- - -希望这个文档能帮助您理解为什么需要屏蔽这些警告,以及它们为什么是安全的! diff --git a/examples/win32-hello/SANITIZER_GUIDE.md b/examples/win32-hello/SANITIZER_GUIDE.md deleted file mode 100644 index 00562a8a..00000000 --- a/examples/win32-hello/SANITIZER_GUIDE.md +++ /dev/null @@ -1,385 +0,0 @@ -# AddressSanitizer 使用指南 - -## 📋 概述 - -AddressSanitizer (ASan) 是一个快速的内存错误检测工具,可以检测: -- 堆缓冲区溢出/下溢 -- 栈缓冲区溢出/下溢 -- 全局缓冲区溢出/下溢 -- 释放后使用(Use-after-free) -- 返回后使用(Use-after-return) -- 重复释放(Double-free) -- 内存泄漏 - ---- - -## 🚀 快速开始 - -### Windows (MSVC) - -```powershell -# 启用 AddressSanitizer -php bin/compiler.php your-app.php --sanitize=address - -# 或简写 -php bin/compiler.php your-app.php --sanitize=addr -``` - -**要求:** -- Visual Studio 2019 16.9+ 或 Visual Studio 2022 -- MSVC 编译器版本 19.29+ - -### Linux/macOS (GCC/Clang) - -```bash -# 单个 sanitizer -php bin/compiler.php your-app.php --sanitize=address - -# 多个 sanitizer(用逗号分隔) -php bin/compiler.php your-app.php --sanitize=address,undefined - -# 可用的 sanitizer 类型: -# - address: 地址错误检测 -# - undefined: 未定义行为检测 -# - thread: 线程竞争检测 -# - memory: 未初始化内存读取检测 -# - leak: 内存泄漏检测 -``` - ---- - -## 🔍 示例输出 - -当检测到内存错误时,AddressSanitizer 会输出详细的错误信息: - -``` -================================================================= -==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 -READ of size 4 at 0x602000000010 thread T0 - #0 0x7ff6abc12345 in main D:\workspace\compiler\examples\test.php:10 - #1 0x7ff6abc67890 in __scrt_common_main_seh - -0x602000000010 is located 0 bytes to the right of 16-byte region [0x602000000000,0x602000000010) -allocated by thread T0 here: - #0 0x7ff6abc98765 in operator new[] - #1 0x7ff6abc12340 in main D:\workspace\compiler\examples\test.php:8 - -SUMMARY: AddressSanitizer: heap-buffer-overflow -================================================================= -``` - ---- - -## 💡 使用建议 - -### 1. 开发阶段启用 - -在开发和测试阶段启用 AddressSanitizer,可以帮助您尽早发现内存错误: - -```powershell -# 编译带 AddressSanitizer 的版本 -php bin/compiler.php debug-test.php --sanitize=address --no-console - -# 运行测试 -.\debug-test.exe -``` - -### 2. 不要与优化同时使用 - -AddressSanitizer 会降低程序性能(约 2x),建议: -- 开发时:`-O0 --sanitize=address` -- 发布时:`-O2`(不使用 sanitizer) - -### 3. 结合调试信息使用 - -```powershell -# 同时启用调试信息和 AddressSanitizer -php bin/compiler.php app.php --debug-info --sanitize=address -``` - -这样可以在错误报告中看到源代码行号。 - ---- - -## 🛠️ 常见用例 - -### 检测数组越界 - -```php -