jze*_*eda 80 c c++ struct function return-type
我的理解是不应该这样做,但我相信我已经看过这样的例子(注意代码在语法上不一定正确,但想法就在那里)
typedef struct{
int a,b;
}mystruct;
Run Code Online (Sandbox Code Playgroud)
然后这是一个功能
mystruct func(int c, int d){
mystruct retval;
retval.a = c;
retval.b = d;
return retval;
}
Run Code Online (Sandbox Code Playgroud)
我明白我们应该总是返回一个指向malloc'ed结构的指针,如果我们想做这样的事情,但我很肯定我已经看到了做类似这样的事情的例子.它是否正确?就个人而言,我总是要么返回一个指向malloc'ed结构的指针,要么只是通过引用函数进行传递并修改那里的值.(因为我的理解是,一旦函数的范围结束,可以覆盖用于分配结构的任何堆栈).
让我们在问题中添加第二部分:这是否因编译器而异?如果是这样,那么桌面编译器的最新版本的行为是什么:gcc,g ++和Visual Studio?
关于此事的想法?
Pab*_*ruz 73
这是非常安全的,这样做并没有错.另外:它不会因编译器而异.
通常,当(像你的例子)你的结构不是太大时,我会认为这种方法甚至比返回malloc结构更好(这malloc
是一项昂贵的操作).
Luc*_*ore 68
这是非常安全的.
你是按价值回归的.如果您通过引用返回,将导致未定义行为的原因是什么.
//safe
mystruct func(int c, int d){
mystruct retval;
retval.a = c;
retval.b = d;
return retval;
}
//undefined behavior
mystruct& func(int c, int d){
mystruct retval;
retval.a = c;
retval.b = d;
return retval;
}
Run Code Online (Sandbox Code Playgroud)
您的代码段的行为完全有效并已定义.它不会因编译器而异.没关系!
我个人总是要么返回一个指向malloc的结构的指针
你不应该.应尽可能避免动态分配内存.
或者只是通过引用该函数进行传递并修改其中的值.
此选项完全有效.这是一个选择问题.通常,如果要在修改原始结构时从函数返回其他内容,则执行此操作.
因为我的理解是,一旦函数的范围结束,可以覆盖用于分配结构的任何堆栈
这是错的.我的意思是,它是正确的,但你返回一个你在函数内创建的结构的副本.从理论上讲.在实践中,RVO可能并且可能会发生.阅读返回值优化.这意味着虽然retval
在函数结束时似乎超出了范围,但它实际上可能是在调用上下文中构建的,以防止额外的副本.这是编译器可以自由实现的优化.
不仅struct
在C中返回一个是安全的(或者class
在C++中,其中struct
-s实际上是class
-es与默认public:
成员),但很多软件正在这样做.
当然,当class
在C++中返回时,该语言指定将调用一些析构函数或移动构造函数,但是在很多情况下,编译器可以对其进行优化.
此外,Linux x86-64 ABI指定通过寄存器(&)返回struct
带有两个标量(例如指针或long
)值的a ,因此非常快速和有效.因此对于该特定情况,返回这样的双标量字段可能比执行任何其他操作更快(例如,将它们存储到作为参数传递的指针中).%rax
%rdx
struct
然后返回这样一个双标量字段struct
要快得多 - malloc
并且返回一个指针.