C:通过引用传递自动变量
C : Passing auto variable by reference
我遇到了一段代码,目前运行良好,但在我看来它的行为未定义,将来可能会引入错误。
伪代码:
void OpertateLoad(int load_id)
{
int value = 0;
/* code to calculate value */
SetLoadRequest(load_id,&value);
/*some processing not involving value**/
}
void SetLoadRequest(int load_id, int* value)
{
/**some processing**/
LoadsArray[load_id] = *value;
/**some processing**/
}
据我所知,C 编译器不保证 Auto
变量的存储位置。它可以是 stack/register(如果可用且适合处理)。
我怀疑如果编译器决定将 value
存储到通用寄存器中,那么 SetLoadRequest
函数可能会引用错误的数据。
我做对了吗?还是我想多了?
我正在为 ARM CORTEX M-4
处理器使用 IARARM
编译器。
------------:编辑:---------
回答总结“无论变量存储在何处,编译器都将确保数据在调用之间保持不变”。
只是想确认一下:这种行为也是真的吗'if a function is returning the address of local auto variable and caller is de-referencing it?'。
如果否,那么 C 标准中是否有任何内容可以保证两种情况下的行为?或者正如我之前所述,它的未定义行为?
据我了解,value
的范围是 OpertateLoad
的正文。但是,SetLoadRequest
分配指向的值,因此 value
的实际值被复制。不涉及未定义的行为。
你想多了。编译器知道,如果 value
在寄存器中,则必须先将其存储到内存中,然后再将指向该内存的指针传递给 SetLoadRequest
.
更一般地说,根本不要考虑堆栈和寄存器。该语言说有一个变量(没有说明它是如何实现的),并且您可以获取它的地址并在另一个函数中使用它来引用该变量。所以你可以!
该语言还说局部变量在离开块时不复存在,因此此权限不会扩展到返回指向局部变量的指针(如果调用者对指针执行任何操作,这将导致未定义的行为)。
I am overthinking it?
是!
编译器会处理这个问题。如果它将它存储在寄存器中,它将知道如何处理它(使用内存加载)。
C11 标准草案 n1570:
6.2.4 Storage durations of objects
6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate. If an
initialization is specified for the object, it is performed each time the declaration or
compound literal is reached in the execution of the block; otherwise, the value becomes
indeterminate each time the declaration is reached.
我遇到了一段代码,目前运行良好,但在我看来它的行为未定义,将来可能会引入错误。
伪代码:
void OpertateLoad(int load_id)
{
int value = 0;
/* code to calculate value */
SetLoadRequest(load_id,&value);
/*some processing not involving value**/
}
void SetLoadRequest(int load_id, int* value)
{
/**some processing**/
LoadsArray[load_id] = *value;
/**some processing**/
}
据我所知,C 编译器不保证 Auto
变量的存储位置。它可以是 stack/register(如果可用且适合处理)。
我怀疑如果编译器决定将 value
存储到通用寄存器中,那么 SetLoadRequest
函数可能会引用错误的数据。
我做对了吗?还是我想多了?
我正在为 ARM CORTEX M-4
处理器使用 IARARM
编译器。
------------:编辑:---------
回答总结“无论变量存储在何处,编译器都将确保数据在调用之间保持不变”。
只是想确认一下:这种行为也是真的吗'if a function is returning the address of local auto variable and caller is de-referencing it?'。
如果否,那么 C 标准中是否有任何内容可以保证两种情况下的行为?或者正如我之前所述,它的未定义行为?
据我了解,value
的范围是 OpertateLoad
的正文。但是,SetLoadRequest
分配指向的值,因此 value
的实际值被复制。不涉及未定义的行为。
你想多了。编译器知道,如果 value
在寄存器中,则必须先将其存储到内存中,然后再将指向该内存的指针传递给 SetLoadRequest
.
更一般地说,根本不要考虑堆栈和寄存器。该语言说有一个变量(没有说明它是如何实现的),并且您可以获取它的地址并在另一个函数中使用它来引用该变量。所以你可以!
该语言还说局部变量在离开块时不复存在,因此此权限不会扩展到返回指向局部变量的指针(如果调用者对指针执行任何操作,这将导致未定义的行为)。
I am overthinking it?
是!
编译器会处理这个问题。如果它将它存储在寄存器中,它将知道如何处理它(使用内存加载)。
C11 标准草案 n1570:
6.2.4 Storage durations of objects
6 For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. (Entering an enclosed block or calling a function suspends, but does not end, execution of the current block.) If the block is entered recursively, a new instance of the object is created each time. The initial value of the object is indeterminate. If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.