这是一个思想实验,不是生产代码,也不是良好的编码风格。
假设我们有这个功能
int find_process_pid_by_name(char* name, int* threads_in_process);
返回指定进程的 PID ,并始终将threads_in_process
存储在所述进程中运行的线程数。
只对 PID 感兴趣的懒惰程序员编写此代码
int pid = find_process_pid_by_name("a process name", &pid);
是否会触发未定义的行为?
答案 0 :(得分:10)
不 - 我不认为这是不明确的行为。在调用函数之前有一个序列点(在参数和表示被调用函数的表达式已被评估之后),并且在被调用函数返回之前还有另一个序列点。在函数完成返回之前,已完成被调用函数执行的pid
上的任何副作用。然后将该函数的结果分配给pid
。毫无疑问,该功能改变了分配的位置。我什么也没看到引起未定义的行为。
我假设被调用函数将int *
参数视为指向单个值的只写指针。如果它从单个值读取,我们需要知道pid
之前已经初始化(正式;在实践中,它不重要)。在上下文中,pid
尚未初始化;函数的结果将初始化它。因此,如果函数从其指针参数读取,从技术上讲,您有未定义的行为。如果函数将指针视为多元素数组的开头并且超出第0个元素,则存在问题。但这些问题有些超出了问题/讨论的预期范围。
答案 1 :(得分:1)
是的,我相信这段代码定义明确。在将返回值复制到调用上下文之前,函数末尾有一个序列点。因此,该函数将首先通过pid
间接分配给threads_in_process
,然后它将返回,然后返回值将分配给pid
。