免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lipingtababa
打印 上一主题 下一主题

[C] c语言编译器是怎么返回结构体的? [复制链接]

论坛徽章:
0
41 [报告]
发表于 2008-06-05 17:59 |只看该作者
原帖由 yecheng_110 于 2008-6-5 17:25 发表

不可能这样做的
这样语义都变了


不变形,这对用户是完全透明的。

论坛徽章:
0
42 [报告]
发表于 2008-06-05 18:05 |只看该作者
原帖由 ew3j 于 2008-6-5 17:59 发表


不变形,这对用户是完全透明的。



不过,这样做这个函数就不能多线程重入了。

论坛徽章:
1
双子座
日期:2015-01-04 14:25:06
43 [报告]
发表于 2008-06-05 18:07 |只看该作者
原帖由 scutan 于 2008-6-5 17:57 发表


嗯。我也是看的汇编,是这个结果。

那本<编程卓越之道> 第二卷  16.7节也是这样讲的。

确实是16.7节
原帖由 lipingtababa 于 2008-6-5 17:56 发表
感谢yecheng_110 (我是噩梦) 的引用,不过你贴的文章是讨论代码段指针存储的,而不是返回值存储的.

scutan    (冬日夜雨) 的说法,有文献可以佐证吗?

  凭记忆抄的 没细看了
16.7 Function Return Values
Most HLLs return function results in one or more CPU registers. Exactly
which register the compiler uses depends on the data type, CPU, and
compiler. For the most part, however, functions return their results in
registers.
On the 80x86, most functions that return ordinal (integer) values
return their function results in the AL, AX, or EAX register. Functions
that return 64-bit values (long long int) generally return the function result
in the EDX:EAX register pair (with EDX containing the HO double word
of the 64-bit value). On 64-bit variants of the 80x86 family, 64-bit compilers
return 64-bit results in the RAX register. On the PowerPC, most compilers
follow the IBM ABI and return 8-, 16-, and 32-bit values in the R3 register.
Compilers for the 32-bit versions of the PowerPC return 64-bit ordinal
values in the R4:R3 register pair (with R4 containing the HO word of the
function result). Presumably, compilers running on 64-bit variants of the
PowerPC can return 64-bit ordinal results directly in R3.
Generally, compilers return floating-point results in one of the CPU’s
(or FPU’s) floating-point registers. On 32-bit variants of the 80x86 CPU family,
most compilers return a floating-point result in the 80-bit ST0 floating-point
register. Although the 64-bit versions of the 80x86 family also provide the same
FPU registers as the 32-bit members, some OSes such as Windows64 typically
use one of the SSE registers (XMM0) to return floating-point values. PowerPC
systems generally return floating-point function results in the F1 floating-point
register. Other CPUs return floating-point results in comparable locations.
Some languages allow a function to return a nonscalar (aggregate)
value. The exact mechanism that compilers use to return large function
return results varies from compiler to compiler. However, a typical solution is
to pass a function the address of some storage where the function can place
the return result. As an example, consider the following short C++ program
whose func function returns a structure object:

The one thing that you should note from these 80x86 and PowerPC
examples is that functions returning large objects often copy the function
result data just prior to returning. This extra copying can take considerable
time, especially if the return result is large. Instead of returning a large
Functions and Procedures 575
structure as a function result, as I’ve done above, it is usually a better
solution to explicitly pass a pointer to some destination storage to a
function that returns a large result and let the function do whatever
copying is necessary. This often saves some time and code. Consider
the following C code that implements this policy:

As you can see, this approach is more efficient because the code doesn’t
have to copy the data twice, once to a local copy of the data and once to the
final destination variable.

论坛徽章:
1
双子座
日期:2015-01-04 14:25:06
44 [报告]
发表于 2008-06-05 18:09 |只看该作者
原帖由 ew3j 于 2008-6-5 18:05 发表



不过,这样做这个函数就不能多线程重入了。

对嘛
你自己都知道这样不行了

论坛徽章:
0
45 [报告]
发表于 2008-06-05 18:13 |只看该作者
原帖由 yecheng_110 于 2008-6-5 18:07 发表

确实是16.7节

  凭记忆抄的 没细看了


你有这个的英文版? 我去借了本中文的在看。

论坛徽章:
0
46 [报告]
发表于 2008-06-05 18:13 |只看该作者
实际上编译器经常隐式传递参数的,比如C++里的this指针。呵呵

论坛徽章:
0
47 [报告]
发表于 2008-06-05 19:01 |只看该作者
The one thing that you should note from these 80x86 and PowerPC
examples is that functions returning large objects often copy the function
result data just prior to returning

这句话是说把返回值从callee函数的栈拷贝到caller函数指定的某处?那么这个某处是在堆上还是栈上?

假设返回的对象大小是不定的,比如返回一个string,那么放在栈上好像不可行.

btw,yecheng_110 (我是噩梦)引用的是哪本书?

论坛徽章:
0
48 [报告]
发表于 2008-06-05 19:13 |只看该作者

回复 #47 lipingtababa 的帖子

肯定是返回到栈上的,因为你的局部变量是在栈上的。对象的大小会在函数中设定的,这是编译器最起码的工作。
他引用的就是<编程卓越之道>第二卷上面的内容。

论坛徽章:
0
49 [报告]
发表于 2008-06-05 19:15 |只看该作者
原帖由 scutan 于 2008-6-5 17:47 发表
C语言返回结构体的时候会进行拷贝,也就是在调用函数之前先将接收返回值的变量的地址传递进去,然后再在被调用的函数返回时使用memcpy将其值拷贝到这个内存中去。所以如果返回的结构体较大,则效率可能会比较低。

这个是不一定的。
编译器也可能直接让被调用者操作接收返回值的结构体。

论坛徽章:
0
50 [报告]
发表于 2008-06-05 19:54 |只看该作者
原帖由 zx_wing 于 2008-6-5 19:15 发表

这个是不一定的。
编译器也可能直接让被调用者操作接收返回值的结构体。


感觉这个也和我刚刚说的那个差不多吧,我说的意思是在函数返回时直接将整个结构体拷贝过去,而您说的是指在函数内部的每次访问都根据这个地址来进行访问。
不过我觉得由于空间局部性的原理,编译器应该不会这样做吧?
我对这个也不熟,还多指教。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP