Code review: * The struct members and variables pointing at string literals should be const. * People do break this all the time but typedefs ending in _t are reserved by POSIX. * Your C99 style struct initializers are valid but it's notable that one popular compiler, MSVC, will not like them. * If we are being idiomatic I would suggest pointer arithmetic to iterate instead of using a counter i.
Style review: * Avoid using NULL in your resume. It has a negative connotation, and makes your resume look bad. * Make use of as many existing libraries as possible, to show that you're not the kind of programmer that wants to invent the wheel on every occasion. * Try to obfuscate your resume a little (but not too much!) As it is written here, your reader can easily guess what the program will do, and he/she will not…
Resume in C
111–115 of 115 posts
Re: Resume in C
#112Earlier quoted context omitted.
And how is this different from char* x; ... if (/*smth*/) { x = "Hello"; } else { x = strdup("Hello"); } ... if (/*smth*/) { free(x); } ? Maybe I'm slow, but I don't see how the union makes a difference.
The difference is that the code may try to execute x = "Hello", and then call free(y) (in case the condition is messed up). So the code will try to free() the pointer to a string literal (because they share the same memory location in the union).
Re: Resume in C
#113Earlier quoted context omitted.
I don't understand your false premises. I've never had C marketed to me as a language that promised safe, perfect code. It does what it says on the tin. However I think you have some false premises: the Linux kernel is huge, has a fairly high turn-over in contributors, and is written in C. Hardly anyone "knows" the entire code base. I've yet to meet anyone who can even name all of the compile switches... some 1000+ o…
There is a big difference between writing C code and C code that is safe from exploits, even Linux isn't immune to it as the daily CVE updates show. http://www.cvedetails.com/vulnerability-list/vendor_id-33/pr...
While the separation of lint from the compiler might have been a mistake made as an early performance trade-off I don't really see how that was a false premise of the philosophy of trusting the programmer. Given the history of trade-offs made in the name of performance it doesn't seem like correctness and safety were big concerns.
Maybe they are now and that's why I find the Mirage project interesting... but C still has its uses and I don't blame C for human error. The specification isn't terribly difficult to digest and the tooling is rather good these days.
Re: Resume in C
#114Earlier quoted context omitted.
The difference is that the code may try to execute x = "Hello", and then call free(y) (in case the condition is messed up). So the code will try to free() the pointer to a string literal (because they share the same memory location in the union).
Yes, but you can do x = "Hello" and then call free(x) and get the exact same error without the union. The union doesn't make a difference.
The point I was making is that char*'s (and other pointer types as well) in unions make it harder to track ownership and lifetime by introducing implicit dependencies between data and increasing complexity with more code paths.
It's much easier to reason about the correctness of the code, when the fields of the data structures are mutated linearly and independently. This is especially important when the code is maintained by a number of people over long time.
Unfortunately, the C language does not have the capability to automatically check the correctness of memory management and object lifetimes, so the developer has to do their best to ensure the correctness of the code. In doing so, some coding practices can be better than others.
I am talking about generally good and bad coding practices here, not about the formal correctness of that particular piece of code. If some code works, then obviously it is correct, even if the code is obfuscated, non-human-readable or maintainable.