免费注册 查看新帖 |

Chinaunix

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

[C++] C++的cout就是个杯具 [复制链接]

论坛徽章:
0
51 [报告]
发表于 2010-03-13 12:40 |只看该作者
回复  reiase


    咱嘴太笨,好像没说清楚
reiase 发表于 2010-03-13 12:38


应该说清楚了,补充的有道理.

论坛徽章:
0
52 [报告]
发表于 2010-03-13 12:51 |只看该作者
比较流行的语言里,大部分都有和printf类似的东西。。
我想知道除了c++,还能在哪个语言里看到iosteram的这种风格?

论坛徽章:
0
53 [报告]
发表于 2010-03-13 12:52 |只看该作者
回复 5# 冻惨鸟
我发现自己写个可变参数函数拼sql更方便,而且效率高

论坛徽章:
0
54 [报告]
发表于 2010-03-13 12:54 |只看该作者
此外我觉得无论cout如何不好用,但在C++里,你没办法Printf一个string类啊

论坛徽章:
0
55 [报告]
发表于 2010-03-13 12:59 |只看该作者
此外我觉得无论cout如何不好用,但在C++里,你没办法Printf一个string类啊
zx_wing 发表于 2010-03-13 12:54



    这个是C++从C继承来的一个缺陷,在其他OO语言里,对象都有运行时的类型信息,会根据格式化输入输出的格式控制符,自动转换对象类型

论坛徽章:
0
56 [报告]
发表于 2010-03-13 13:28 |只看该作者
回复 54# zx_wing
这个不是问题,自己写个函数封装printf就行了
其实c++的cout也得重载操作符,一样的。。

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

c99 6.2.5
26 A pointer to void shall have the same representation and alignment requirements as a
pointer to a character type.

...

All pointers to structure types shall have the same representation and alignment requirements
as each other. All pointers to union types shall have the same representation and
alignment requirements as each other. Pointers to other types need not have the same representation or alignment requirements.

6.3.2.3 Pointers
1 A pointer to void may be converted to or from a pointer to any incomplete or object
type. A pointer to any incomplete or object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer.

...

7 A pointer to an object or incomplete type may be converted to a pointer to a different
object or incomplete type. If the resulting pointer is not correctly aligned57) for the
pointed-to type, the behavior is undefined.



尤其需要注意的是, c99放弃了c89中的某个保证(也有可能是我没在c99中找到相应的段落):
c89 6.3.4 Cast operators

A pointer to an object or incomplete type may be converted to a pointer to a different
object type or a different incomplete type. The resulting pointer might not be valid if it is
improperly aligned for the type pointed to. It is guaranteed, however. that a pointer to an
object of a given alignment may be converted to a pointer to an object of the same alignment
or a less strict alignment and back again: the result shall compare equal to the
original pointer (An object that has character type has the least strict alignment.)


举个假象的例子:(可能你又要觉得我很无聊了……)
C语言规定char是最小的可寻址单位。

假设编译器会将所有的int对齐到4字节边界。
那么, int类型的指针, 就可以少用2个bit。

再假设该平台要求的最大对齐边界是8 。
假设编译器会激昂所有struct 对齐到8字节编辑。
那么, 所有struct指针可以少用3个bit。

所以, 对对齐有更强需求的指针, 如int和struct, 转换到有较弱对齐需求的指针, 且不丢失信息。
这是有保证的。

当int或者struct指针转换到char指针时, 末尾可以填充0 。
而且没有丢失信息: 当转换回正确的指针类型时, 再把末尾的0截断即可。

反之不行。 将char指针转换为int或者struct指针时, 末尾信息就被丢弃了。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
58 [报告]
发表于 2010-03-13 18:13 |只看该作者
char *template = load_template_from_file("template.txt");
printf(tempate,v1,v2,v3,...);
reiase 发表于 2010-03-13 12:37


你可以把这个问题在具体一些。
就是printf? 还是类似printf那样的, 使用变长参数+格式化字符串的函数?

再考虑性能开销问题,cout使用运算符重载的方案,cout<<v1<<v2<<v3产生三次函数调用,并且三份函数调用的汇编代码,从时间和空间角度来看,都三倍于printf
reiase 发表于 2010-03-13 12:37


这你就想当然了。
printf里面那个大大的switch, 和某一个operator<<(T const& )能比么?

三份调用的代码? 只是多了若干个call指令。 压入的参数个数是相同的。

cout慢在背后的一整个体系。
就重载运算符这点上, 肯定是比运行时解析类型要快。

再有,cout/cin的没有可供检查的返回值,只能使用C++的异常机制,对于某些使用C++又不想要异常机制的项目,这点很成为问题。
reiase 发表于 2010-03-13 12:37


你又胡说了。
cout/cin默认是采用状态检查的函数。 而异常反而是需要开启的。


所以我觉得printf提供更多实际实惠,而cout/cin提供更多语法上的实惠。但不得不说,标榜OO更符合人类思维习惯的C++,把输入输出实现成了最有悖人类思维的诡异方式。
reiase 发表于 2010-03-13 12:37


cout/cin和OO扯上什么关系了? 我从不认为自己是为了更OO而使用cout/cin的。
而且别忘了, printf实际上是 fprintf(stdout, ... )

另外, 整个人类都被你代表了。


至于类型安全问题,可以说是C语言的问题,在Python这些强类型语言下,格式化输入输出是提供类型安全的
reiase 发表于 2010-03-13 12:37

这个是C++从C继承来的一个缺陷,在其他OO语言里,对象都有运行时的类型信息,会根据格式化输入输 ...
reiase 发表于 2010-03-13 12:59


确实是类型安全的, 准确的说,是运行时
C/C++敢将过多的运行时类型检查塞入语言中吗?

另外, 别提到C++就想到OO。 C++是多范式, OO只是最不起眼的一种。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
59 [报告]
发表于 2010-03-13 18:17 |只看该作者
比较流行的语言里,大部分都有和printf类似的东西。。
我想知道除了c++,还能在哪个语言里看到iosteram的这种风格?
greensnow 发表于 2010-03-13 12:51


pascal是。
我记得java和C#中, 格式化字符串反而是后来添加的。

这个不是问题,自己写个函数封装printf就行了
其实c++的cout也得重载操作符,一样的。。
greensnow 发表于 2010-03-13 12:51


这当然是个问题。
看15楼。

论坛徽章:
0
60 [报告]
发表于 2010-03-13 19:43 |只看该作者
1. 三次函数调用比一个switch走三次要效率高吗?这个我真没测过,现代CPU上函数调用要不要保存寄存器状态?咱不是计算机专业的,不是很清楚...还有一个疑问就是三次cout导致陷入内核的次数会不会多于printf,也就是三次cout会不会导致缓存上的低效?求牛人给解释下

2. scanf的返回值是成功读取数据的个数,但是在cin链上,你用状态检查函数能够检测出第几个读取出错吗?每次调用完cin,要不要都调用状态检查函数得瑟下?或者借用某位老兄的例子,多线程环境下,你用状态检查函数,能检查到啥?要不要先上个锁再调用状态检查函数?生产环境只能用异常吧,不然cin不声不响少读个数据

3. 那个格式化模板实例化的例子是Python下的,我写了个等价的C版本。Python原版例子是:
a = {'a':1,'b':2}
template = """ a=%(a)d, b=%(b)d """
print template%a
前段时间写CGI,反反复复用这个,真的爽死了。Python字符串的格式化操作支持传入字典类型(也就是hash)。这个是纯运行时的,C++那个cout不太可能实现。

4. OO已经是C++特性中最不起眼的一个了...我想起了前两天看到的那个ACE帖子:学之者生,用之者死
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP