免费注册 查看新帖 |

Chinaunix

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

[C++] 引用变量占用内存空间吗? [复制链接]

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
11 [报告]
发表于 2011-08-02 17:46 |只看该作者
回复 10# liwangli1983


    我也认为是这样的。作为函数形式参数的时候,其底层实现实际上是指针实现。所以引用也会占据空间(在运行栈帧上)。

    但是作为全局引用的时候,编译器可以将别名直接替换成实际的对象地址。对于全局变量的维护发生在编译期,因此编译器可以采取任何方案。所以全局引用是不占空间的。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
12 [报告]
发表于 2011-08-03 01:00 |只看该作者
回复 8# captivated

哈, 如果没看那集, 估计我也想不到这是那个毒舌大胃腹黑扣鼻女……

上来干嘛呢……

觉得这个帖子:
1. 诸多回复可看出果然误会很广
2. 不同于oop/coding style那样, 各自有各自的看法。 这属于一个一是一二是二的问题, 没什么好争论的。
所以就回了一下。

但其实作用不大, 误会的依然误会……  所以, 上来干嘛呢……
来看苦逼程序员抱怨苦逼人生吗?


最后:

  1. int var = 12;
  2. static int& ref = var;
  3. int main(void) {
  4. #ifndef REF
  5.       return var;
  6. #else
  7.       return ref;
  8. #endif
  9. }
复制代码
cl -W3 -O1 draft.cpp -link -nodefaultlib -entry:main

只列出重要信息
dumpbin -headers -disasm draft.exe
            1000 entry point (00401000)    // main函数
   .text name
       6 virtual size
  00401000: A1 00 20 40 00     mov         eax,dword ptr ds:[00402000h] ; 这是直接访问变量
  00401005: C3                 ret
   .data name
       8 virtual size  // 8字节, 引用变量依然存在


cl -DREF -W3 -O1 draft.cpp -link -nodefaultlib -entry:main
除了如下的汇编代码, 其他信息同上
  00401000: A1 04 20 40 00     mov         eax,dword ptr ds:[00402004h] ; 这两行是通过指针访问变量
  00401005: 8B 00              mov         eax,dword ptr [eax]
  00401007: C3                 ret


gcc -Wall -O1 -fomit-frame-pointer -nostdlib -s draft.cpp -Dmain=entry

dumpbin -headers -disasm a.exe
            1000 entry point (00401000)
   .text name
      1C virtual size
  00401000: A1 00 20 40 00     mov         eax,dword ptr ds:[00402000h]
  00401005: C3                 ret
SECTION HEADER #2
   .data name
       8 virtual size

gcc -DREF -Wall -O1 -fomit-frame-pointer -nostdlib -s draft.cpp -Dmain=entry

同样, 只有产生的代码不同
  00401000: A1 04 20 40 00     mov         eax,dword ptr ds:[00402004h]
  00401005: 8B 00              mov         eax,dword ptr [eax]
  00401007: C3                 ret


我想说的只是: 至少在我用过的编译器(cl/gcc/icc/clang)以及i386上, 引用都是有大小的, 引用的语意需要间接的获取这个信息。
后面的一些结论就越来越无聊了……
依然是这些平台, 函数参数是肯定占空间的; 自动变量经常被优化。
静态引用变量这问题真比较无聊……   是这个结果也好, 不是也罢……
印象中我还真没写过"通过引用(而非直接)访问静态变量"这种代码……

论坛徽章:
0
13 [报告]
发表于 2011-08-03 01:11 |只看该作者
引用可以放 struct 里的,所以必须占空间

struct A
{
     int &r;
};

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
14 [报告]
发表于 2011-08-03 10:00 |只看该作者
回复 12# OwnWaterloo


    呃. 那个确实。

    这个回复算是解决了我的疑惑~ 话说,cl的那些编译选项我就没见过, 或者说我根本没怎么用过cl...
    gcc的那些编译选项也不知道神马意思. 看来, 花时间认真学习下gcc和各种binary tools的manual确实是必要的...

    我觉得g++生成的汇编码比较难懂,不是因为AT&T语法格式的问题, 比如cc编译C代码生成的汇编码, 还是比较容易明白的, 至少栈帧结构神马的很容易看出来...
    可是因为C++引入异常机制之后,g++需要在函数栈帧结构上加入支持异常机制的相关信息吧,相对来说比较复杂. 我对gas(as)还不够熟悉吧...

    比如,我写个只反映一层函数调用的代码,simple.c:
   
   
    gcc -S simple.c -o simpleC.asm:
   
    嗯,那个栈帧结构还是很清楚滴...

    g++ -S simple.c -o simpleCPP.asm:
   
    _Z3addii, 我知道你就是add的马甲,别装了.
    .LFB0是神马? .LFE0是神马?
    .LFB1是神马? .LFE1是神马?
   
    毫无疑问, .LFB和.LFE应该是g++为支持异常机制在基本栈帧结构上增加的料. 问题是我对C++的异常处理了解甚少,所以不了解这些加的料都怎么弄的,以及什么意思...
    扯一下... 关于cfront. cfront是把C++代码编译处理成C代码的编译器, C代码再由C编译器转换为汇编码. 那这种 C++ source code -> cfront -> C compiler -> ...的处理方式,毫无疑问是无法在汇编码级别往栈帧上加料的(因为C语言的函数栈帧结构,编译出来就那样子),所以, cfront是无法实现异常处理机制的,没法stack unwind... 或者说... 使用cfront这种方式非常难以实现异常处理机制(要做到平台体系无关是吧, 不能写个setjump之类的库就算是吧...)... 不知这个扯得对否?...

    OwnWaterloo兄, 这个...神马时候讲下g++的异常处理呢(呃C++的异常处理才对吧...)? 那个.LFB和.LFE若有研究, 望告知, 求解惑~

论坛徽章:
0
15 [报告]
发表于 2011-08-03 11:47 |只看该作者
回复 14# captivated
http://baiy.cn/doc/cpp/inside_exception.htm   只提供链接,还没到档次去学习

论坛徽章:
0
16 [报告]
发表于 2011-08-03 23:03 |只看该作者
看到头晕了。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
17 [报告]
发表于 2011-08-08 18:53 |只看该作者
回复 14# captivated

只研究过Windows下的, 而且忘得差不多了……
建议不单看-S的输出, 有时候需要看链接后的输出才行……

论坛徽章:
0
18 [报告]
发表于 2011-09-08 18:09 |只看该作者
留个座位,去接老婆去了。

论坛徽章:
0
19 [报告]
发表于 2011-09-08 18:41 |只看该作者
本帖最后由 幻の上帝 于 2011-09-08 18:42 编辑

不是unspecified么。就是说不管占不占,哪怕同一个程序中在一个地方占了另一个地方不占都是合理的。

ISO C++03 8.3.2/3 & ISO C++0x(N3242) 8.3.2/4
It is unspecified whether or not a reference requires storage (3.7).

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
20 [报告]
发表于 2011-09-08 21:23 |只看该作者
回复 19# 幻の上帝

所以我一直想避免说它是否占空间……  而是说它有大小……
比如5楼的例子, 那些局部变量就很难说是否占空间, C++肯定不会去做这方面的规定。
而且, 相对于一般的局部变量, 引用变量还无法取得引用变量的地址, 更容易优化。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP