神奇的代码和神奇的while(0)

写了这么长时间的C/C++程序,发现C/C++真的很灵活呢!

1. 神奇的代码

下面看看一些神奇的用法:

我们反汇编一下看看编译器对上面的代码会做些什么。
注意:–表示两个尖括号。被转义了。。。

	char* a[2]={"hello","world"};
  4013bd:	c7 45 e8 00 00 44 00 	movl   $0x440000,0xffffffe8(%ebp)
  4013c4:	c7 45 ec 06 00 44 00 	movl   $0x440006,0xffffffec(%ebp)
	char** b = [AND]a[1];
  4013cb:	8d 45 e8             	lea    0xffffffe8(%ebp),%eax
  4013ce:	83 c0 04             	add    $0x4,%eax
  4013d1:	89 45 e4             	mov    %eax,0xffffffe4(%ebp)
	a[1];a[4];a[-0xFFFFFFFF]; //-0xFFFFFFFF == 1
	1;2;3;0xdead;	//神奇,猜猜编译后是不是消失了
	;;;;;;;	//算不算 NOP ?
	for(0;0;0)0;	//我喜欢0
	while(0);	//你说gcc编译后,会不会判断0是不是等于0?
	switch(0)default: 	//这句貌似可以忽略它的存在

         晕啊,上面的代码都被鄙视了

	cout--b[0xFFFFFFFF]--endl; 	//b[-1] = a[0]   索引是int的,所以正负都可以。
  4013d4:	8b 45 e4             	mov    0xffffffe4(%ebp),%eax
  4013d7:	83 e8 04             	sub    $0x4,%eax
 

     和想的一样,减去了4个字节,就是a[0]了。

  4013da:	8b 00                	mov    (%eax),%eax
  4013dc:	89 44 24 04          	mov    %eax,0x4(%esp)
  4013e0:	c7 04 24 c0 33 44 00 	movl   $0x4433c0,(%esp)
  4013e7:	e8 ec ac 03 00       	call   43c0d8 <__ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
  4013ec:	c7 44 24 04 a8 ae 43 	movl   $0x43aea8,0x4(%esp)
  4013f3:	00
  4013f4:	89 04 24             	mov    %eax,(%esp)
  4013f7:	e8 34 8c 02 00       	call   42a030 <__ZNSolsEPFRSoS_E>

	cout--cout--cout--cout--cout; //貌似输出的是一串指针

     请问为什么输出参数0x4433c4呢?这个值是如何得来的?

  4013fc:	c7 04 24 c4 33 44 00 	movl   $0x4433c4,(%esp)
  401403:	e8 28 e4 01 00       	call   41f830 <__ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv>
  401408:	89 c6                	mov    %eax,%esi
  40140a:	c7 04 24 c4 33 44 00 	movl   $0x4433c4,(%esp)
  401411:	e8 1a e4 01 00       	call   41f830 <__ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv>
  401416:	89 c7                	mov    %eax,%edi
  401418:	c7 04 24 c4 33 44 00 	movl   $0x4433c4,(%esp)
  40141f:	e8 0c e4 01 00       	call   41f830 <__ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv>
  401424:	89 c3                	mov    %eax,%ebx
  401426:	c7 04 24 c4 33 44 00 	movl   $0x4433c4,(%esp)
  40142d:	e8 fe e3 01 00       	call   41f830 <__ZNKSt9basic_iosIcSt11char_traitsIcEEcvPvEv>
  401432:	89 44 24 04          	mov    %eax,0x4(%esp)
  401436:	c7 04 24 c0 33 44 00 	movl   $0x4433c0,(%esp)
  40143d:	e8 3e 8c 02 00       	call   42a080 <__ZNSolsEPKv>
  401442:	89 5c 24 04          	mov    %ebx,0x4(%esp)
  401446:	89 04 24             	mov    %eax,(%esp)
  401449:	e8 32 8c 02 00       	call   42a080 <__ZNSolsEPKv>
  40144e:	89 7c 24 04          	mov    %edi,0x4(%esp)
  401452:	89 04 24             	mov    %eax,(%esp)
  401455:	e8 26 8c 02 00       	call   42a080 <__ZNSolsEPKv>
  40145a:	89 74 24 04          	mov    %esi,0x4(%esp)
  40145e:	89 04 24             	mov    %eax,(%esp)
  401461:	e8 1a 8c 02 00       	call   42a080 <__ZNSolsEPKv>
	__asm__("nop;nop");
  401466:	90                   	nop    
  401467:	90                   	nop    

下面一句又被鄙视了。

	{{{{{{{{{{{{{{{{{{{{{{{}}}}}}}}}}}}}}}}}}}}}}}
}
好神奇啊~~~
以前就听说用pascal、basic、lisp、java、fortran、angela、 abc、ada、c#、d、tom、
perl、python、z、brainfuck等等语言写的东西都可以用c来做到呢!

2. 神奇的while(0)

说一个很有用的东西。 例如定义一个宏,如果有多个语句时,推荐使用下面的形式: #define exchange( a, b ) do{ int t=a; a=b; b=t; }while(0) 而不是 #define exchange( a, b ) { int t=a; a=b; b=t; } 第二种在下面的情形下后果很严重。 if( a>b || fb_is_holy_ox ) exchange( a, b ); else nothing(); 预编译之后语句变成了: if( a>b || fb_is_holy_ox ) { int t=a; a=b; b=t; }; //if语句结束 else //此处出错 nothing();

神奇的代码和神奇的while(0)》有3个想法

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据