Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should Local Variable Initialisation Be Mandatory?

The maintenance problems that uninitialised locals cause (particularly pointers) will be obvious to anyone who has done a bit of c/c++ maintenance or enhancement, but I still see them and occasionally hear performance implications given as their justification.

It's easy to demonstrate in c that redundant initialisation is optimised out:

$ less test.c
#include <stdio.h>
main()
{
#ifdef INIT_LOC
    int a = 33;
    int b;
    memset(&b,66,sizeof(b));
#else
    int a;
    int b;
#endif
    a = 0;
    b = 0;
    printf ("a = %i, b = %i\n", a, b);
}

$ gcc --version
gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

[Not Optimised:]

$ gcc test.c -S -o no_init.s; gcc test.c -S -D INIT_LOC=1 -o init.s; diff no_in
it.s init.s
22a23,28
>       movl    $33, -4(%ebp)
>       movl    $4, 8(%esp)
>       movl    $66, 4(%esp)
>       leal    -8(%ebp), %eax
>       movl    %eax, (%esp)
>       call    _memset
33a40
>       .def    _memset;        .scl    3;      .type   32;     .endef

[Optimised:]

$ gcc test.c -O -S -o no_init.s; gcc test.c -O -S -D INIT_LOC=1 -o init.s; diff
 no_init.s init.s
$

So WRT performance under what circumstances is mandatory variable initialisation NOT a good idea?

IF applicable, no need to restrict answers to c/c++ but please be clear about the language/environment (and reproducible evidence much preferred over speculation!)

like image 406
schmick Avatar asked Sep 26 '08 14:09

schmick


1 Answers

Short answer: declare the variable as close to first use as possible and initialize to "zero" if you still need to.

Long answer: If you declare a variable at the start of a function, and don't use it until later, you should reconsider your placement of the variable to as local a scope as possible. You can then usually assign to it the needed value right away.

If you must declare it uninitialized because it gets assigned in a conditional, or passed by reference and assigned to, initializing it to a null-equivalent value is a good idea. The compiler can sometimes save you if you compile under -Wall, as it will warn if you read from a variable before initializing it. However, it fails to warn you if you pass it to a function.

If you play it safe and set it to a null-equivalent, you have done no harm if the function you pass it to overwrites it. If, however, the function you pass it to uses the value, you can pretty much be guaranteed failing an assert (if you have one), or at least segfaulting the second you use a null object. Random initialization can do all sorts of bad things, including "work".

like image 134
hazzen Avatar answered Oct 13 '22 23:10

hazzen