gcc 编译器函数实参构造问题。

Enter空格 2016-08-30 11:38:18
#include <stdio.h>

class OBJ{};
void test(OBJ&)
{
printf("test");
}

int main()
{
OBJ obj;
test(obj);
test(OBJ()); //gcc编译错误
return 0;
}


上面这段代码VS2010+,编译无压力。
但gcc无论哪个版本,哪个标准,都不能编译通过。
gcc认死理把 test(OBJ());中的OBJ()当右值,
但test(OBJ());这语法,明显没错,并且更简洁易懂吧?

因为这样的原因,导致封装的好多东西,调用好傻,本来一行搞定的东西
必须两行才能实现。
对gcc不是很了解,请问下有什么编译命令可以绕过这个问题吗?
或者gcc编译命令应该到哪学习了解去?
...全文
531 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2016-09-02
  • 打赏
  • 举报
回复
VC延伸了函数返回值的生命周期,到引用他的函数结束。 实际是这个函数的实参的生存周期, 按照C++标准,应该是 在函数调用参数传入函数之后,尚未跳入函数体之前 到函数调用结束的任一时刻。 这给编译器两个选择: 1)在函数调用参数传入函数之后,尚未跳入函数体之前,临时对象Obj() 结束生命周期。 2)函数调用结束,立即结束,实参的生命周期。 这两种方式,应该都可以的。 因为他是临时量。
太上绝情 2016-08-31
  • 打赏
  • 举报
回复
你的函数改一个临时变量有什么意义呢?
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
即使从作用域来说 这个临时对象你觉得会扩展到test函数的上一层函数中么?他在初始化test调用的参数时候构造的那么他的作用于怎么会扩展到test函数的上一层函数中去呢?
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 20 楼 akirya 的回复:
[quote=引用 15 楼 mymixing 的回复:] [quote=引用 4 楼 akirya 的回复:] 这个代码错的是VS,G++是正确的,这个代码不应该编译通过。
test(OBJ())这段代码语义完全正确吧。 除了gcc认死理的右值。 [/quote] 不正确[/quote] 如果不考虑OBJ()是右值这个事。 单纯从语法语义来讲,test(OBJ()),有任何问题吗? test内部对OBJ()的操作有任何会引发错误的问题吗?
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
这个临时对象的生存期 在test调用结束就要被释放掉。这点你觉得有异议么?
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
如果你认同是一个临时对象。那么再看看是不是右值 An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 19 楼 pengzhixi 的回复:
[quote=引用 18 楼 mymixing 的回复:] [quote=引用 16 楼 pengzhixi 的回复:] 好吧 看来你不太认同这个是右值。 那么你认同是一个临时对象不?
栈上的,都是临时对象。[/quote] 你把这个临时对象的范围放大了。[/quote] 严格来讲这个临时对象的生存期 应该在test函数的上一层函数中, 所以test引用这个对象,语义完全没问题的。 明显vs在这方面做的更加合理。
  • 打赏
  • 举报
回复
引用 15 楼 mymixing 的回复:
[quote=引用 4 楼 akirya 的回复:] 这个代码错的是VS,G++是正确的,这个代码不应该编译通过。
test(OBJ())这段代码语义完全正确吧。 除了gcc认死理的右值。 [/quote] 不正确
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
引用 18 楼 mymixing 的回复:
[quote=引用 16 楼 pengzhixi 的回复:] 好吧 看来你不太认同这个是右值。 那么你认同是一个临时对象不?
栈上的,都是临时对象。[/quote] 你把这个临时对象的范围放大了。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 16 楼 pengzhixi 的回复:
好吧 看来你不太认同这个是右值。 那么你认同是一个临时对象不?
栈上的,都是临时对象。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 14 楼 lianshaohua 的回复:
个人也同样认为G++的处理是正确的,而vs的处理存在问题;如果这种用法,传入&是没有必要的,增加const吧
怎么没用,一个是两行调用,一个一行搞定。 OBJ()实际是一个比较复杂的对象,在函数内部是要使用的,不能const
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
好吧 看来你不太认同这个是右值。 那么你认同是一个临时对象不?
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 4 楼 akirya 的回复:
这个代码错的是VS,G++是正确的,这个代码不应该编译通过。
test(OBJ())这段代码语义完全正确吧。 除了gcc认死理的右值。
ztenv 版主 2016-08-30
  • 打赏
  • 举报
回复
个人也同样认为G++的处理是正确的,而vs的处理存在问题;如果这种用法,传入&是没有必要的,增加const吧
ri_aje 2016-08-30
  • 打赏
  • 举报
回复
g++ 正确。 vs2010 是垃圾。
xskxzr 2016-08-30
  • 打赏
  • 举报
回复
引用 10 楼 mymixing 的回复:
[quote=引用 8 楼 paschen 的回复:] 如果test的函数写成 void test(const OBJ&) 则没问题 所以如果函数类不修改传入的引用对象时,建议都用const进行修饰
呃。。就是要用OBJ,所以才没声明为const 。。[/quote] 用const_cast。 不过既然是传入的右值,理应不会对其修改,调用的也应当是OBJ的const方法。 如果OBJ里本来应该声明为const的方法没有声明为const,那就是这个类本身的设计问题。
pengzhixi 2016-08-30
  • 打赏
  • 举报
回复
Where a parameter is of const reference type a temporary object is introduced if needed
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 8 楼 paschen 的回复:
如果test的函数写成 void test(const OBJ&) 则没问题 所以如果函数类不修改传入的引用对象时,建议都用const进行修饰
呃。。就是要用OBJ,所以才没声明为const 。。
Enter空格 2016-08-30
  • 打赏
  • 举报
回复
引用 5 楼 adlay 的回复:
为何不把 test 函数改成 void test(const OBJ&) 或 void test(OBJ&&) 而要去改每一处调用的地方呢?
1.void test(const OBJ&),我封装的函数内部要使用OBJ对象,目的是接口统一,确保易用性。 2.void test(OBJ&&),项目用的编译器不支持c++11.
paschen 版主 2016-08-30
  • 打赏
  • 举报
回复
如果test的函数写成 void test(const OBJ&) 则没问题 所以如果函数类不修改传入的引用对象时,建议都用const进行修饰
加载更多回复(24)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧