Jayesh
Jayesh

Reputation: 4903

Which one is better to use in C and C++ programming?

Is there any difference between the following two code snippets? Which one is better to use? Is one of them faster?

case 1:

int f(int x) 
{
    int a;
    if(x)
        a = 42;
    else
        a = 0;
    return a; 
}

case 2:

int f(int x) 
{
    int a;
    if(x)
        a = 42;
    return a; 
}

Upvotes: 1

Views: 177

Answers (6)

Actually that both snippets can return totally different results, so there is no better...

In case 2 you can return a non initialized variable a, which may result on a garbage value other than zero...

if you mean this:

int f(int x) 
{
    int a = 0;
    if(x)
        a = 42;
    return a; 
}

then I would say is that better, since is more compact(but you are saving only an else, not much computational wasted anyways)

Upvotes: 4

Mike Nakis
Mike Nakis

Reputation: 62129

The question is not "which one is better". The question is "will both work?"

And the answer is no, they will not both work. One is correct, the other is out of the question. So, performance is not even an issue.

The following results in a having either an "indeterminate value" or an "unspecified value" mentioned in the c99 standard, sections 3.17.2 and 3.17.3 (Probably the latter, though it is not clear to me.)

int a;
if(x)
    a = 42;
return a; 

This in turn means that the function will return an unspecified value. This means that that are absolutely no guarantees as to what value you will get.

If you are unlucky, you might get zero, and thus proceed to use the above terrible piece of code without knowing that you are bound to have lots of trouble with it later.

If you are lucky, you will get something like 0x719Ab32d right away, so you will immediately know that you messed up.

Any decent C compiler will give you a warning if you try to compile this, so the fact that you are asking this question means that you do not have a sufficient number of warnings enabled. Do not try to write C code (or any code) without the maximum possible number of warnings enabled; it never leads to any good. Find out how to enable warnings on your C compiler, and enable as many of them as you can.

Upvotes: 3

Andriy Berestovskyy
Andriy Berestovskyy

Reputation: 8544

Note: I assume uninitialized a in your second snippet is a type and it is int a = 0.

We can use gdb to check the difference:

(gdb) list f1
19  {
20      int a;
21      if (x)
22          a = 42;
23      else
24          a = 0;
25      return a;
26  }
(gdb) list f2
28  int f2(int x)
29  {
30      int a = 0;
31      if (x)
32          a = 42;
33      return a;
34  }

Now let's look at the assembler code with -O3:

(gdb) disassemble f1
Dump of assembler code for function f1:
   0x00000000004007a0 <+0>: cmp    $0x1,%edi
   0x00000000004007a3 <+3>: sbb    %eax,%eax
   0x00000000004007a5 <+5>: not    %eax
   0x00000000004007a7 <+7>: and    $0x2a,%eax
   0x00000000004007aa <+10>:    retq   
End of assembler dump.
(gdb) disassemble f2
Dump of assembler code for function f2:
   0x00000000004007b0 <+0>: cmp    $0x1,%edi
   0x00000000004007b3 <+3>: sbb    %eax,%eax
   0x00000000004007b5 <+5>: not    %eax
   0x00000000004007b7 <+7>: and    $0x2a,%eax
   0x00000000004007ba <+10>:    retq   
End of assembler dump.

As you can see, there is no difference. Let us disable the optimizations with -O0:

(gdb) disassemble f1
Dump of assembler code for function f1:
   0x00000000004006cd <+0>: push   %rbp
   0x00000000004006ce <+1>: mov    %rsp,%rbp
   0x00000000004006d1 <+4>: mov    %edi,-0x14(%rbp)
   0x00000000004006d4 <+7>: cmpl   $0x0,-0x14(%rbp)
   0x00000000004006d8 <+11>:    je     0x4006e3 <f1+22>
   0x00000000004006da <+13>:    movl   $0x2a,-0x4(%rbp)
   0x00000000004006e1 <+20>:    jmp    0x4006ea <f1+29>
   0x00000000004006e3 <+22>:    movl   $0x0,-0x4(%rbp)
   0x00000000004006ea <+29>:    mov    -0x4(%rbp),%eax
   0x00000000004006ed <+32>:    pop    %rbp
   0x00000000004006ee <+33>:    retq   
End of assembler dump.
(gdb) disassemble f2
Dump of assembler code for function f2:
   0x00000000004006ef <+0>: push   %rbp
   0x00000000004006f0 <+1>: mov    %rsp,%rbp
   0x00000000004006f3 <+4>: mov    %edi,-0x14(%rbp)
   0x00000000004006f6 <+7>: movl   $0x0,-0x4(%rbp)
   0x00000000004006fd <+14>:    cmpl   $0x0,-0x14(%rbp)
   0x0000000000400701 <+18>:    je     0x40070a <f2+27>
   0x0000000000400703 <+20>:    movl   $0x2a,-0x4(%rbp)
   0x000000000040070a <+27>:    mov    -0x4(%rbp),%eax
   0x000000000040070d <+30>:    pop    %rbp
   0x000000000040070e <+31>:    retq   
End of assembler dump.

Now there is a difference and the first version in average for random arguments x will be faster as it has one mov less that the second one.

Upvotes: 2

Deb S
Deb S

Reputation: 544

You don't need extra space for a in either case - you can do something like this -

int f(int x) 
{
    if(x)
        return  42;
    else
        return  0;
}

BTW in your second function you have not initialised a.

Upvotes: 0

FrankTheTank_12345
FrankTheTank_12345

Reputation: 580

I would prefer this (your second snippet):

int f(int x) {

    int a = 0;

    if (x) {
        a = 42;
    }
    return a;
}
  • Everything should always have braces. Even if now I only have one line in the if block, I made add more later.
  • I don't put the braces on their own lines because it's pointless waste of space.
  • I rarely put the block on the same line as the conditional for readability.

Upvotes: 0

O.Rares
O.Rares

Reputation: 1071

In case your second code is

int f(int x) 
{
    int a=0;
    if(x)
        a = 42;
    return a; 
}

and not

int f(int x) 
{
    int a;
    if(x)
        a = 42;
    return a; 
}

It doesn't matter.The compiler will convert them to same optimized code

Upvotes: 0

Related Questions