【发布时间】:2020-12-01 10:34:25
【问题描述】:
在处理调用 Python 脚本的批处理脚本时偶然发现了这一点。
在 Python 脚本中,我调用了 sys.exit(-1),它将 %ERRORLEVEL% 设置为 4294967295。在得知 Windows 使用 32 位无符号整数后,我将其更改为 sys.exit(4294967295),但现在 %ERRORLEVEL% 为 -1 .
为什么它会反其道而行之? sys.exit(-1) 是有道理的,因为它的 (2^32) -1 并与环绕一起存储,但为什么使用 32 位无符号整数的最大值会转换为 -1?是不是下面的 C 里面有什么东西?
【问题讨论】:
-
来自documentation of
sys.exit():大多数系统要求它在 0-127 范围内,否则会产生未定义的结果 -
@EugeneSh。但是 Windows 文档处理 0-[(2^32)-1] 的范围。所以 C 实现中一定有一些东西。
-
@pstatix 该范围没有在任何地方记录。我为各种平台的应用程序的退出值阅读了各种建议,但我没有在任何地方阅读真正的规范。仅根据返回类型为 int 或 unsigned int 的编译器/库/解释器定义了可以使用函数 main 的哪些变体,但是据我所知,Windows 没有通用规范。在 C 和 C++ 标准中,int 被定义为能够包含至少 -32,767 到 +32,767 的范围(我没记错时从 C99 开始)。
-
@pstatix 在 Linux 上,仅使用 0 到 127 的值作为应用程序特定返回码到父进程是安全的,因为 Linux 内核的各种系统函数已经解释了具有特殊含义的更高值,如 @ 987654322@、wait 等。像
SIGTERM和SIGINT这样的Linux 信号应该导致退出应用程序,信号值+ 128 导致“用户”退出范围限制为0 到127。 -
Python 在 Modules/main.c 中以
Py_Main开头。初始化由几个 C 文件实现,例如 Python/pylifecycle.c、Python/preconfig.c 和 Python/initconfig.c 以及 Modules/getpath.c(或 PC/getpathp.c)。最终它会得到一个运行函数,例如 Python/pythonrun.c 中的PyRun_FileExFlags。该文件通过PyParser_ASTFromFileObject和PyAST_CompileObject进行解析和编译。有了代码对象,它在 Python/ceval.c 中调用PyEval_EvalCode,它创建一个框架对象来评估代码,最后在PyEval_EvalFrame中执行,即执行字节码的循环。
标签: python c windows cmd error-code