Shortcut evaluation instead of doing if(condition) expression;

北慕城南 提交于 2020-05-30 08:32:26

问题


Recently, I've come across a piece of code like this (not the real one, but a shorter example based upon it):

#include <stdio.h>

int main()
{
  int n;

  printf ("n? ");  
  scanf ("%d", &n);

  n%2 && printf ("N is odd\n");  /* <-- this is it */

  return 0;
}

In case anybody didn't get it, this code is the equivalent of:

int main()
{
  int n;

  printf ("n? ");  
  scanf ("%d", &n);

  if (n%2) 
    printf ("N is odd\n");

  return 0;
}

A disassembly of this code compiled with GCC 4.4.5-8 for x86-64 bits gives this for the part in which n is evaluated and printf() is conditionally called:

        andl    $1, %eax
        testb   %al, %al
        je      .L3
        movl    $.LC2, %eax
        movq    %rax, %rdi
        movl    $0, %eax
        call    printf
        testl   %eax, %eax
.L3:
        movl    $0, %eax
        leave
        ret

Sounds like the code an if statement would generate. The "standard" way gives this:

        andl    $1, %eax
        testb   %al, %al
        je      .L2
        movl    $.LC2, %edi
        call    puts
.L2:
        movl    $0, %eax
        leave
        ret

Slighly shorter, and a bit faster too, because the compiler can use puts() instead of printf(), as it has detected that printf() is being used to print a single string, and its return value is not used. The former example must evaluate the second expression after && because the first one evaluated to true, so printf() had to be used to get a value to evaluate with.

So my point is: Could this shortcut evaluation trick be considered good coding? It works but... does it any better other than helping to win one-liner C contests? Judging by the example I've provided I'd say no, but may it exist an example that proves otherwise?

NOTE: while trying to compile the original code, the compiler even generated an ICE (MingW 2.95.2) with a text error saying something about "error while executing do_jump" or something like that.


回答1:


This technique is not useful in general as it is contrary to generally-accepted convention and leads to unreadable code. (Note that this technique is acceptable in other languages, such as perl, where it is a commonly-used idiom.)

One place you may be forced to use this technique is in a function-like macro.

#define foo(x, y) (((x) % 2) && (y))

You cannot write the macro as

#define foo(x, y) if ((x) % 2) (y)

Because that would mess up things like

if (a) foo(x, y); else bar();

The usual workaround of

#define foo(x, y) do { if ((x) % 2) (y); } while (0)

does not work with the comma operator.

for (i = 0, foo(x, y); i < 10; i++) ...

That said, any such use of this idiom should be well-commented.



来源:https://stackoverflow.com/questions/20930483/shortcut-evaluation-instead-of-doing-ifcondition-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!