开发者

Code before the first 'case' in a switch-statement

开发者 https://www.devze.com 2022-12-17 18:45 出处:网络
In C it\'s possible to write code before the first case label. Are there any cases for which it is useful to do this or is it just a \'dead block of code\' ?

In C it's possible to write code before the first case label. Are there any cases for which it is useful to do this or is it just a 'dead block of code' ?

E.g.:

switch (...)    {
  {
  开发者_Python百科  int a = 0x2a;
    printf("%d\n", a);
  }
  case 0:
    ...
}


I think this is less a feature than an artifact of how C treats switch/case—as just a series of jump targets without restrictions on the syntax. That's why Duff's device works and that's also why the code before the first case won't ever run.

If you look at the generated assembly you'll see that the code will just be jumped over:

    mov ecx, DWORD PTR _x$[ebp]
    mov DWORD PTR tv64[ebp], ecx
    cmp DWORD PTR tv64[ebp], 0                  ; here begins the switch
    je  SHORT $LN1@main                         ; jump to case 0
    jmp SHORT $LN4@main                         ; jump out of the switch
; Line 8
    mov DWORD PTR _a$752[ebp], 42
; Line 9
    mov edx, DWORD PTR _a$752[ebp]              ; here we have the dead code
    push    edx
    push    OFFSET $SG754
    call    _printf
    add esp, 8
$LN1@main:                                      ; and here case 0
; Line 12
    push    OFFSET $SG756
    call    _printf
    add esp, 4
$LN4@main:
; Line 15
    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0


The C standard document has an example that explains exactly the behavior of this type of construct (6.8.4.2/7 "The switch statement"):

EXAMPLE In the artificial program fragment

switch (expr)
{
    int i = 4;
    f(i);
case 0:
    i  =  17;
    /*  falls through into default code  */
default:
    printf("%d\n", i);
}

the object whose identifier is i exists with automatic storage duration (within the block) but is never initialized, and thus if the controlling expression has a nonzero value, the call to the printf function will access an indeterminate value. Similarly, the call to the function f cannot be reached.

So even though this is permitted, it's easily one of those "just because you can doesn't mean you should" situations. The construct is confusing and can easily lead to using an uninitialized variable since it can be very unclear whether and where the initialization occurs.


It can be useful to declare variables that have a scope limited to the switch block (but be aware that any initialisers for those variables will be skipped):

switch (...)
{
    int n;

    case 0:
    ...
}

In theory, you could also put code there that you get to using goto.


I don't understand what your after. Why not just put the code before the case?

int a = 0x2a;
printf("%d\n", a);
switch (...)    {
case 0:
...
}

Isn't that the same as what you intend ? (apart from in your example the code would never run if the compiler doesn't complain.)

0

精彩评论

暂无评论...
验证码 换一张
取 消