I am reading the FreeBSD coding style and am quite liking it (as I like vertically compact code). There is however this:
Initialize all Variables
You shall always initialize variables. Always. Every time. gcc with the flag -W may catch operations on uninitialized variables, but it may also not.Justification
More problems than you can believe are eventually traced back to a pointer or variable left uninitialized.
When there is no appropriate initial value for a variable, isn't it much better to leave it without a value. That way the compiler will probably catch reading it uninitialized. i am not talking about T *p = NULL, which is a trap representation and might (or may not) be quite useful, but rather int personal_number = 0 /* but 0 is a valid personal number!!*/
To clarify, in response to abasu's comment, my example is trying to illustrate cases when there are no available invalid values. I have asked a question and was answered that using impossible values to mark errors or other conditions is awesome. But it is not always the case. Examples are plentiful: 8bit pixel value, velocity vector, etc.
One valid alternative to "Always initialize variables", that I can see is:
//logical place for declarations
T a;
/*code, for example to set up the environment for evaluating a*/
a = fooForA();
/*more code*/
fooThatUsesA(a);
This way if initialization is forgotten, there will be warning and the bug will be fixed, removing the warning.
Are all integers valid personal numbers?
If not, then use an invalid value to initialize personal_number.
If they are, then even when you have not initialized personal_number yourself it still holds a value that is a valid personal number -- but that value is unknown. So initialize it to 0 anyway -- you have not introduced a problem (valid number before, valid number after), the only difference is that the number is now known to you.
Of course in both cases it would be better to not use an integer literal for initialization, but rather do something like this:
enum { INVALID_PERSONAL_NUMBER = -1 }
int personal_number = INVALID_PERSONAL_NUMBER;
Compilers often don't catch reading variables uninitialized. Instead, they're likely to use that information to make assumptions about the rest of the code to perform optimization, possibly introducing new and worse bugs:
int get_personal_number(const char *name)
{
int personal_number;
if (name != NULL) {
/* look up name in some array */
personal_number = ...
}
return personal_number;
}
An optimising compiler will infer that name cannot be NULL and eliminate the check. Similar issues have caused security bugs; see e.g. http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
Instead, rewrite your functions to initialize variables with their eventual correct value at declaration; this may require writing lots of small functions, using ternary expressions etc., which is generally better style anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With