Conflating pointers with arrays: C's biggest mistake? (2009)
This is IMHO by far NOT C' biggest mistake. Not even close. A typical compiler will even warn you when you do something stupid with arrays in function definitions (-Wsizeof-array-argument is the default nowadays).<p>On the other hand, UBE (undefined, or unspecified behavior) are probably the nastiest stuff that can bite you in C.<p>I have been programming in C for a very, very long time, and I am still getting hit by UBE time to time, because, eh, you tend to forget "this case".<p>Last time, it took me a while to realize the bug in the following code snippet from a colleague (not the actual code, but the idea is there):<p>struct ip_weight {
  in_addr_t ip;
  uint64_t weight;
};<p>const struct ip_weight ipw1 = {0x7F000001, 1};
const struct ip_weight ipw2 = {0x7F000001, 1};<p>const uint32_t hash1 = hash_function(&ipw1, sizeof(ipw1));
const uint32_t hash2 = hash_function(&ipw2, sizeof(ipw2));<p>The bug: hash1 and hash2 are not the same. For those who are fluent in C UBE, this is obvious, and you'll probably smile. But even for veterans, you tend to miss that after a long day of work.<p>This, my friends, is part of the real mistakes in C: leaving too many UBE. The result is coding in a minefield.<p>[You probably found the bug, right ? If not: the obvious issue is that 'struct ip_weight' needs padding for the second field. And while all omitted fields are by the standard initialized to 0 when you declare a structure on the stack, padding value is undefined; and gcc typically leave padding with stack dirty content.]