if (xcnt < 2) if (xcnt != 0) return; else { date = x[0]; time = x[1]; }
But C associates an else with the closest unmatched if inside the same pair of braces. The compiler executes the above code the same as the following:
if (xcnt < 2) { if (xcnt != 0) { return; } else { date = x[0]; time = x[1]; } }
In other words, nothing at all happens when xcnt is 2 or greater. Again, using braces for all conditional statements comes to the rescue:
if (xcnt < 2) { if (xcnt != 0) { return; } } else { date = x[0]; time = x[1]; }
Although full use of braces increases the number of lines of source code, braces make future program modifications much easier and less error-prone. With braces delimiting segments of conditional code, adding and deleting subordinate statements requires less careful checking of how else clauses and subordinate statements match up with the if statements.
Another, elegant, solution is to define the following macros:
#define IF { if ( #define THEN ) { #define ELSE } else { #define ELSEIF } else if ( #define ENDIF } }
We could then code our previous example as:
IF xcnt < 2 THEN IF xcnt != 0 THEN return; ENDIF ELSE date = x[0]; time = x[1]; ENDIF
Once the macros are replaced with their corresponding definitions, the code is executed the same as the previous example. This style is guaranteed to cause traditional C programmers apoplexy, but they'll forget about it when they chase down their next bug. Meanwhile, your code can be readable and reliable.