这是一个思想实验,不是生产代码,也不是良好的编码风格。
假设我们有这个功能
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);
它会触发未定义的行为吗?
不 - 我不认为这是不确定的行为。在调用函数之前有一个序列点(在参数和表示被调用函数的表达式已被评估之后),并且在被调用函数返回之前还有另一个序列点。任何副作用 pid
由函数执行的函数已在函数完成返回之前完成。然后将该函数的结果赋值给 pid
。毫无疑问,该功能改变了分配的位置。我没有看到任何调用未定义行为的东西。
我假设被调用的函数处理 int *
参数作为指向单个值的只写指针。如果它从单个值读取,我们需要知道 pid
之前已经初始化(正式;在实践中,它无关紧要)。在上下文中, pid
尚未初始化;函数的结果将初始化它。因此,如果函数从其指针参数读取,从技术上讲,您有未定义的行为。如果函数将指针视为多元素数组的开头并访问超出第0个元素,则存在问题。但这些问题有些超出了问题/讨论的预期范围。
是的,我相信这段代码定义明确。在将返回值复制到调用上下文之前,函数末尾有一个序列点。所以函数将首先分配给 pid
间接通过 threads_in_process
,然后它将返回,然后返回值将被分配给 pid
。