加0前缀使数字被当作八进制解释:017=15合法,018因含非法数字8报错;c/c++沿袭此规则,而js(es6+)、python3已禁用,跨语言移植易出错。

加 0 前缀会让编译器把数字常量当作八进制解释,而不是十进制——这是 C/C++ 从 1970 年代沿袭下来的语法约定,不是 bug,是设计事实。
为什么 017 是 15,而 018 直接报错
八进制只允许数字 0–7。所以:
-
017→ 八进制的17=1×8 + 7 = 15(合法) -
018→ 出现了非法数字8,GCC/Clang 会报错:invalid digit "8" in octal constant -
00、07、0123都合法;08、09、019全部非法
0 前缀在不同语言中的行为不一致
C++ 和 C 严格遵循“前导 0 = 八进制”,但其他语言做了修正:
- JavaScript(ES5 及以前):也认
017为八进制;ES6 起已**禁用**该语法,017会报 SyntaxError - Python 2:支持
017;Python 3:直接报错,必须写0o17 - Java:从 Java 7 开始,
017合法,但08、09报错;Java 8+ 仍保留该行为
这意味着:跨语言移植代码时,带前导 0 的数字常量最容易 silently 出问题——尤其当它看起来像十进制(比如 007)却实际是八进制。
真正危险的是和宏、配置值混在一起
常见误用场景:
- 定义端口号:
#define PORT 08080→ 编译失败,因为08080含8 - 权限掩码写成
0755没问题,但若手误写成0758,GCC 不报错而是静默截断或警告,运行时权限异常 - 用
std::stoi("017", nullptr, 0)时,第三个参数为0表示“自动推断进制”,它会按 C 风格识别前导0→ 返回 15;但std::stoi("018", nullptr, 0)会抛std::invalid_argument
最易被忽略的一点:这个规则只作用于**整数字面量**,对浮点数无效(0123.45 是非法写法,编译器直接拒掉),也不影响字符串解析逻辑——但只要你在源码里写了带前导 0 的整数,它的值就已由编译器在编译期锁死,和你“心里想的十进制”无关。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











