RELATEED CONSULTING
相关咨询
选择下列产品马上在线沟通
服务时间:9:30-18:00
你可能遇到了下面的问题
关闭右侧工具栏
更深入一点理解switch语句及c/c++对const的处理
  • 作者:xiaoxiao
  • 发表时间:2020-12-23 10:39
  • 来源:未知

更深入一点理解 switch 语句 及 c/c++ 对 const 的处理                                    谢煜波------------------------------------------------

转载请注明原作者,以出处~~

------------------------------------------------

前段时间在论坛上看见台湾李维在<<Borland传奇>>一书中对windows编程模式中,消息处理部分有如下的一些分析:他说,在消息处理循环中,一般的形式是这样的MSG msg ;switch( msg ){        case WM_XXXXXXX :                ....        case WM_XXXXXXX :                ....        case WM_XXXXXXX :                ....} ;李维说,这种模式是很低效的,因应经过汇编后,这种C代码会产生如下的汇编代码        cmp .... .....        jnz .... .....        cmp .... .....        jnz .... .....        cmp .... .....        jnz .... .....如果你的 case 足够多,比如,你有一万条消息需要处理,而不幸的是你把一条最常用的消息放在了最后一位,那么当这条消息要得到处理,会首先经过一万次的cmp与jnz, 李维认为,这是非常非常低效的,实在是低效的忍无可忍,无需再忍~~:P

在起初,我也是这样认为的,但近来的阅读及实验却发现,这种看法非常片面,今天就来谈谈这个问题( 所有实验在 linux 平台下完成 )

首先看一到用 c 编写的程序/* -------------------- filename : ta.c --------------- */int switch_test_first( int x ){        int res ;        switch( x ){                case 100 :                        res = 1 ;                        break ;                case 102 :                        res = 2 ;                        break ;                case 103 :                        res = 3 ;                        break ;        }        return res ;}然后,我们用 gcc 将它编译成汇编文件( 使用 -S 开关 )gcc -S ta.c 将得到如下的汇编文件( ta.s )        .file   "ta.c"        .text.globl switch_test_first        .type   switch_test_first,@functionswitch_test_first:        pushl   %ebp        movl    %esp, %ebp        subl    $8, %esp        movl    8(%ebp), %eax        .file   "ta.c"        .text.globl switch_test_first        .type   switch_test_first,@functionswitch_test_first:        pushl   %ebp        movl    %esp, %ebp        subl    $8, %esp        movl    8(%ebp), %eax        movl    %eax, -8(%ebp)        cmpl    $102, -8(%ebp)          // 1        je      .L4                     // 2        cmpl    $102, -8(%ebp)          // 3            jg      .L8                     // 4        cmpl    $100, -8(%ebp)          // 5        je      .L3                     // 6        jmp     .L2                     // 7.L8:        cmpl    $103, -8(%ebp)        je      .L5        jmp     .L2.L3:        movl    $1, -4(%ebp)        jmp     .L2.L4:        movl    $2, -4(%ebp)        jmp     .L2.L5:        movl    $3, -4(%ebp).L2:        movl    -4(%ebp), %eax        leave        ret.Lfe1:        .size   switch_test_first,.Lfe1-switch_test_first        .ident  "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"