编译器细节决定编程细节的一个小例子.
凑一下热闹:t1.cpp//C++
//.....................
int main()
{
int* p;
int* p1;
p1=new (std::nothrow)int[-1];//失败后返回NULL
if(p1==NULL)
{
printf("\r\n p1 error....");
}
p = new int[-1]; //失败后抛出异常
if(p==NULL)//当失败后实际上执行不到这.
{
printf("\r\n p error....");
}
return(0);
}
gridserver1:/share/suse linux/root/c # g++ -g t1.cpp
gridserver1:/share/suse linux/root/c # gdb a.out
This GDB was configured as "x86_64-suse-linux"...
Using host libthread_db library "/lib64/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x40083c: file t1.cpp, line 10.
(gdb) disass main //如下看到,实际上编译器把c/c++源代码中的不同new的用法处理成了不同的调用.
Dump of assembler code for function main:
0x0000000000400834 <main+0>: push %rbp
0x0000000000400835 <main+1>: mov %rsp,%rbp
0x0000000000400838 <main+4>: sub $0x10,%rsp
0x000000000040083c <main+8>: mov $0x500d50,%esi
0x0000000000400841 <main+13>: mov $0xfffffffffffffffc,%rdi
0x0000000000400848 <main+20>: callq0x4006d8 <_ZnamRKSt9nothrow_t@plt> //失败直接返回NULL的new
0x000000000040084d <main+25>: mov %rax,0xfffffffffffffff8(%rbp)
0x0000000000400851 <main+29>: cmpq $0x0,0xfffffffffffffff8(%rbp)
0x0000000000400856 <main+34>: jne 0x400867 <main+51>
0x0000000000400858 <main+36>: mov $0x400988,%edi
0x000000000040085d <main+41>: mov $0x0,%eax
0x0000000000400862 <main+46>: callq0x4006c8 <printf@plt>
0x0000000000400867 <main+51>: mov $0xfffffffffffffffc,%rdi
0x000000000040086e <main+58>: callq0x4006b8 <_Znam@plt>//失败抛出异常的new
0x0000000000400873 <main+63>: mov %rax,0xfffffffffffffff0(%rbp)
0x0000000000400877 <main+67>: cmpq $0x0,0xfffffffffffffff0(%rbp)
0x000000000040087c <main+72>: jne 0x40088d <main+89>
0x000000000040087e <main+74>: mov $0x400998,%edi
0x0000000000400883 <main+79>: mov $0x0,%eax
0x0000000000400888 <main+84>: callq0x4006c8 <printf@plt>
0x000000000040088d <main+89>: mov $0x0,%eax
0x0000000000400892 <main+94>: leaveq
0x0000000000400893 <main+95>: retq
End of assembler dump.
(gdb) n
The program is not being run.
(gdb) r
Starting program: /share/suse linux/root/c/a.out
Breakpoint 1, main () at t1.cpp:10
10 p1=new (std::nothrow)int[-1];
(gdb) n
11 if(p1==NULL)
(gdb) n
13 printf("\r\n p1 error....");
(gdb) n
16 p = new int[-1];
(gdb) n
terminate called after throwing an instance of 'std::bad_alloc'
what():St9bad_alloc
p1 error....
Program received signal SIGABRT, Aborted.
0x00002b591b4bcbb5 in raise () from /lib64/libc.so.6
(gdb)
[ 本帖最后由 system888net 于 2009-5-18 22:53 编辑 ] 对缺省new int[...]的处理方法无法说它是一优点,当然也无法说是确点
lz解答一下这个吧
同主题阅读:突然发现printf还是比cout好啊[上一主题] [下一主题]【分页: 1 】
[本篇全文] [本篇作者:derliyan] [进入讨论区] [返回顶部]
1
发信人: derliyan (天子剑), 信区: CPlusPlus
标题: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 22:56:50 2009), 站内
特别是多线程程序时能保证每次输出的都是一个完整的句子
--
/*--------------------------------*/
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:antijp] [进入讨论区] [返回顶部]
2
发信人: antijp (antijp), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 22:59:57 2009), 站内
莫非是一次调用 vs 多次调用?
【 在 derliyan (天子剑) 的大作中提到: 】
: 标题: 突然发现printf还是比cout好啊
: 发信站: 水木社区 (Thu May 21 22:56:50 2009), 站内
:
:
: 特别是多线程程序时能保证每次输出的都是一个完整的句子
: --
: /*--------------------------------*/
:
: ※ 来源:·水木社区 http://newsmth.net·
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:derliyan] [进入讨论区] [返回顶部]
3
发信人: derliyan (天子剑), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:12:05 2009), 站内
比如输出 cout<<"a="<<1<<endl;
在并行编程时如果两个线程:
可能是 a=a=
1
1
或者别的啥情况,
printf("a=%d\n",1)就不会出现这些情况了
不知道cout是否有别的方法控制出现这些情况,刚试验并行程序,还没有深入了解
【 在 antijp (antijp) 的大作中提到: 】
: 莫非是一次调用 vs 多次调用?
--
/*--------------------------------*/
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:shrek2099] [进入讨论区] [返回顶部]
4
发信人: shrek2099 (怪物Shrek), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:24:46 2009), 站内
flush?
【 在 derliyan (天子剑) 的大作中提到: 】
: 比如输出 cout<<"a="<<1<<endl;
: 在并行编程时如果两个线程:
: 可能是 a=a=
: ...................
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:sunseraphic] [进入讨论区] [返回顶部]
5
发信人: sunseraphic (愛と友情 勇気と努力 希望と勝利 夢と未来), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:29:54 2009), 站内
先把要输出的都缓存到一个stringstream里然后再cout这个string?
不知道cout支不支持多个buffer,然后为每个线程分配一个专用buffer...
【 在 derliyan (天子剑) 的大作中提到: 】
: 比如输出 cout<<"a="<<1<<endl;
: 在并行编程时如果两个线程:
: 可能是 a=a=
: ...................
--
资深宅男iux在Internatianl Otaku Culture Research杂志发表论文指出:
好人只是好人,而女人需要找的首先是男人,如果可能,她们也希望能找到好男人.
那么在只有好人和男人的情况下,女人肯定只能去选男人而不是好人.虽然是和狗
一样的,好歹那也是"男人".
——这一理论被视为“好〇都让狗〇了”理论的引理
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:junmaing] [进入讨论区] [返回顶部]
6
发信人: junmaing (浅蓝), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:30:46 2009), 站内
【 在 derliyan (天子剑) 的大作中提到: 】
: 比如输出 cout<<"a="<<1<<endl;
~~~~~~~~~~~~~~也许cout把这个作为两个语句来进行操作的吧
: 在并行编程时如果两个线程:
: 可能是 a=a=
: ...................
--
▕╲ __▕╲
__╲ ╱▕__╲
╲╱▕ThinkPad
╱ ╲╱
╲
╱
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:sunseraphic] [进入讨论区] [返回顶部]
7
发信人: sunseraphic (愛と友情 勇気と努力 希望と勝利 夢と未来), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:32:41 2009), 站内
一个<<就是一次 operator<< 的调用吧,cout成了线程间共享的对象了,要不每次用co
ut之前加锁?用完再解锁?
【 在 junmaing (浅蓝) 的大作中提到: 】
: ~~~~~~~~~~~~~~也许cout把这个作为两个语句来进行操作的吧
--
资深宅男iux在Internatianl Otaku Culture Research杂志发表论文指出:
好人只是好人,而女人需要找的首先是男人,如果可能,她们也希望能找到好男人.
那么在只有好人和男人的情况下,女人肯定只能去选男人而不是好人.虽然是和狗
一样的,好歹那也是"男人".
——这一理论被视为“好〇都让狗〇了”理论的引理
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:overcomeunic] [进入讨论区] [返回顶部]
8
发信人: overcomeunic (功夫茶), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:33:50 2009), 站内
这个不靠谱吧
cout怎么知道自己现在处的是哪个线程?
【 在 sunseraphic (愛と友情 勇気と努力 希望と勝利 夢と未来) 的大作中提到: 】
: 先把要输出的都缓存到一个stringstream里然后再cout这个string?
: 不知道cout支不支持多个buffer,然后为每个线程分配一个专用buffer...
--
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:sunseraphic] [进入讨论区] [返回顶部]
9
发信人: sunseraphic (愛と友情 勇気と努力 希望と勝利 夢と未来), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Thu May 21 23:35:37 2009), 站内
对流的研究不深,只是记得貌似流可以指定一个非默认的streambuffer,不过那个好像
是在构造的时候指定的,也不支持多个,看样子是不行...
【 在 overcomeunic (功夫茶) 的大作中提到: 】
: 这个不靠谱吧
: cout怎么知道自己现在处的是哪个线程?
--
资深宅男iux在Internatianl Otaku Culture Research杂志发表论文指出:
好人只是好人,而女人需要找的首先是男人,如果可能,她们也希望能找到好男人.
那么在只有好人和男人的情况下,女人肯定只能去选男人而不是好人.虽然是和狗
一样的,好歹那也是"男人".
——这一理论被视为“好〇都让狗〇了”理论的引理
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:antijp] [进入讨论区] [返回顶部]
10
发信人: antijp (antijp), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 00:15:02 2009), 站内
这个应该展开成了多次函数调用,所以会有这个结果。如果函数里面放了 lock,并且 lock 实现为 FIFO,那出现这个结果就更正常了……
【 在 derliyan (天子剑) 的大作中提到: 】
: 标题: Re: 突然发现printf还是比cout好啊
: 发信站: 水木社区 (Thu May 21 23:12:05 2009), 站内
:
: 比如输出 cout<<"a="<<1<<endl;
:
: 在并行编程时如果两个线程:
: 可能是 a=a=
: 1
: 1
: 或者别的啥情况,
: printf("a=%d\n",1)就不会出现这些情况了
:
: 不知道cout是否有别的方法控制出现这些情况,刚试验并行程序,还没有深入了解
:
: 【 在 antijp (antijp) 的大作中提到: 】
: : 莫非是一次调用 vs 多次调用?
:
: --
: /*--------------------------------*/
:
: ※ 来源:·水木社区 http://newsmth.net·
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:RoachCock] [进入讨论区] [返回顶部]
11
发信人: RoachCock (我的饭盒我的饭), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 00:28:04 2009), 站内
如果当初这样设计就好了:
class locked_ostream
{
public:
locked_ostream(ostream& os):os(os), locked(true){os.lock();}
locked_ostream(locked_ostream&& rhs):os(rhs.os), locked(rhs.locked){
rhs.locked = false;
}
~locked_ostream(){if (locked) os.unlock();}
template <typename T>
locked_ostream& operator<<(T& value){os << value; return *this;}
private:
ostream& os;
bool locked;
};
template <typename T>
locked_ostream operator<<(ostream& os, const T& value)
{
return locked_ostream(os << value);
}
【 在 antijp (antijp) 的大作中提到: 】
: 这个应该展开成了多次函数调用,所以会有这个结果。如果函数里面放了 lock,并且 lock 实现为 FIFO,那出现这个结果就更正常了……
--
努力推导方程式,早日掌握C语言。
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:amuzing] [进入讨论区] [返回顶部]
12
发信人: amuzing (day day paper), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 00:52:08 2009), 站内
我经常这么干:
#define coutx _coutx().lvalue()
class _coutx : public std::stringstream
{
public:
~_coutx() { std::cout << str(); }
_coutx& lvalue() { return *this; }
};
然后用的时候这样
coutx << "a=" << 1 << endl;
【 在 derliyan (天子剑) 的大作中提到: 】
: 比如输出 cout<<"a="<<1<<endl;
: 在并行编程时如果两个线程:
: 可能是 a=a=
: ...................
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:antijp] [进入讨论区] [返回顶部]
13
发信人: antijp (antijp), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 01:30:49 2009), 站内
【 在 RoachCock (我的饭盒我的饭) 的大作中提到: 】
: 标题: Re: 突然发现printf还是比cout好啊
: 发信站: 水木社区 (Fri May 22 00:28:04 2009), 站内
:
: 如果当初这样设计就好了:
: class locked_ostream
: {
: public:
: locked_ostream(ostream& os):os(os), locked(true){os.lock();}
: locked_ostream(locked_ostream&& rhs):os(rhs.os), locked(rhs.locked){
^^引用的引用?这个能正常用么?我印象中好像不能弄这样的东西吧?
: rhs.locked = false;
: }
: ~locked_ostream(){if (locked) os.unlock();}
: template <typename T>
: locked_ostream& operator<<(T& value){os << value; return *this;}
: private:
: ostream& os;
: bool locked;
: };
:
: template <typename T>
: locked_ostream operator<<(ostream& os, const T& value)
: {
: return locked_ostream(os << value);
: }
这个技巧真邪恶,用拷贝构造让新创建的对象放弃操纵 lock……
:
: 【 在 antijp (antijp) 的大作中提到: 】
: : 这个应该展开成了多次函数调用,所以会有这个结果。如果函数里面放了 lock,并且 lock 实现为 FIFO,那出现这个结果就更正常了……
:
:
: --
: 努力推导方程式,早日掌握C语言。
:
:
: ※ 来源:·水木社区 newsmth.net·
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:derliyan] [进入讨论区] [返回顶部]
14
发信人: derliyan (天子剑), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 01:36:22 2009), 站内
还是printf 简单点,
再考虑数据的格式的话 ,
用<< 时 setprecision(),setw(),
一写一长趟,好麻烦,
>> 倒真是很方便
【 在 amuzing (day day paper) 的大作中提到: 】
: 我经常这么干:
: #define coutx _coutx().lvalue()
: class _coutx : public std::stringstream
: ...................
--
/*--------------------------------*/
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:meteor1113] [进入讨论区] [返回顶部]
15
发信人: meteor1113 (刘欣), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 07:11:32 2009), 站内
【 在 derliyan (天子剑) 的大作中提到: 】
: 比如输出 cout<<"a="<<1<<endl;
: 在并行编程时如果两个线程:
: 可能是 a=a=
: 1
: 1
: 或者别的啥情况,
: printf("a=%d\n",1)就不会出现这些情况了
你确定吗?我用printf也会经常出现乱的情况的。要是在printf之后加入fflush好像能好些
: 不知道cout是否有别的方法控制出现这些情况,刚试验并行程序,还没有深入了解
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:derliyan] [进入讨论区] [返回顶部]
16
发信人: derliyan (天子剑), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 08:46:46 2009), 站内
确定用 printf没有出现混乱,
我在vs2005和vs2008上都试过,
【 在 meteor1113 (刘欣) 的大作中提到: 】
: 你确定吗?我用printf也会经常出现乱的情况的。要是在printf之后加入fflush好像能好些
--
/*--------------------------------*/
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:GougoGou] [进入讨论区] [返回顶部]
17
发信人: GougoGou (木笑鱼), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 09:47:53 2009), 站内
那是因为你没碰到特定情况。你用以下C语言代码试试:
#include <stdio.h>
int main(int argc, char **argv)
{
char* a = NULL;
printf("Haha");
*a = 'a';
return 0;
}
Haha应该是打不出来的。因为执行"*a = 'a'"的时候就段错误了,程序都还没有flush的机会。
【 在 derliyan (天子剑) 的大作中提到: 】
: 确定用 printf没有出现混乱,
: 我在vs2005和vs2008上都试过,
--
※ 来源:·水木社区 http://newsmth.net·
[本篇全文] [本篇作者:amuzing] [进入讨论区] [返回顶部]
18
发信人: amuzing (day day paper), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 09:50:10 2009), 站内
printf 比 cout 简单... 历史的倒退啊
那估计是你用不着打印什么struct、class,都是些简单数据类型吧
<< 的威力就这么被无视了...
【 在 derliyan (天子剑) 的大作中提到: 】
: 还是printf 简单点,
: 再考虑数据的格式的话 ,
: 用<< 时 setprecision(),setw(),
: ...................
--
※ 来源:·水木社区 newsmth.net·
[本篇全文] [本篇作者:Tinro] [进入讨论区] [返回顶部]
19
发信人: Tinro (天若|清风涧|不知所云), 信区: CPlusPlus
标题: Re: 突然发现printf还是比cout好啊
发信站: 水木社区 (Fri May 22 09:53:50 2009), 站内
似乎是1x的 右值引用 vs2010已经支持这个了
不过我还是没看懂....
【 在 antijp (antijp) 的大作中提到: 】
: 标题: Re: 突然发现printf还是比cout好啊
: 发信站: 水木社区 (Fri May 22 01:30:49 2009), 站内
:
:
: 【 在 RoachCock (我的饭盒我的饭) 的大作中提到: 】
: : 标题: Re: 突然发现printf还是比cout好啊
: : 发信站: 水木社区 (Fri May 22 00:28:04 2009), 站内
: :
: : 如果当初这样设计就好了:
: : class locked_ostream
: : {
: : public:
: : locked_ostream(ostream& os):os(os), locked(true){os.lock();}
: : locked_ostream(locked_ostream&& rhs):os(rhs.os), locked(rhs.locked){
: ^^引用的引用?这个能正常用么?我印象中好像不能弄这样的东西吧?
: : rhs.locked = false;
: : }
: : ~locked_ostream(){if (locked) os.unlock();}
: : template <typename T>
: : locked_ostream& operator<<(T& value){os << value; return *this;}
: : private:
: : ostream& os;
: : bool locked;
: : };
: :
: : template <typename T>
: : locked_ostream operator<<(ostream& os, const T& value)
: : {
: : return locked_ostream(os << value);
: : }
: 这个技巧真邪恶,用拷贝构造让新创建的对象放弃操纵 lock……
: :
: : 【 在 antijp (antijp) 的大作中提到: 】
: : : 这个应该展开成了多次函数调用,所以会有这个结果。如果函数里面放了 lock,并且 lock 实现为 FIFO,那出现这个结果就更正常了……
: :
: :
: : --
: : 努力推导方程式,早日掌握C语言。
: :
: :
: : ※ 来源:·水木社区 newsmth.net·
:
:
: --
:
: ※ 来源:·水木社区 newsmth.net·
--
※ 来源:·水木社区 newsmth.net·
tcon,335,254845,254846,254847,254848,254849,254850,254851,254852,254853,254854,254855,254856,254857,254858,254861,254863,254866,254867,254868 不懂C++的飘过
回复 #1 system888net 的帖子
第一個new有進行強制type casting,所以compiler在front end 做parsing的時候會產生type casting operator的中間碼(也可能是annotate在new這個node上頭),在其後builtin function expansion時便挑選了不同的builtin function了 哗众取宠是 LZ 一向的发贴作风
:outu: :outu: :outu: :outu: :outu:
页:
[1]