Results of the 2015 Underhanded C Contest
underhanded-c.org
underhanded-c.org
> In contrast there are masters in the martial arts who learned their art as a means of survival and became masters in a realistic and hostile environment. We don’t have anyone like this in the programming profession, or at least I haven’t met any.
Charles H. Moore springs to mind.
Can you expand on this?
“I wish I knew what to tell you that would lead you to write good Forth. I can demonstrate. I have demonstrated in the past, ad nauseam, applications where I can reduce the amount of code by 90% percent and in some cases 99%. It can be done, but in a case by case basis. The general principle still eludes me.”
A friend of mine posted this a couple years ago: https://news.ycombinator.com/item?id=7950190
It's fantastic meeting people who learned to program because they had to. They have a totally different perspective on it.
I'm sick of all the needless complexity in what people push. I'm old enough to have seen it repeat in many fads over time. I've seen designs that beautifully and simply (for user/developer) handled their requirements. I've even seen the master programmers he thinks don't exist that write maintainable, good code under deadlines. I've seen amateurs following good principles come close enough. So, I'd like to see more people emulating the principles of mastery he espouses using any proven method to get there and avoiding common pitfalls.
A significant rise in amateurs on that path would itself deliver a better baseline than what today's experts are pushing. I'll take a well-trained amateur that hates complexity over an expert any day. 80/20 rule says I don't need many experts anyway for most jobs.
I would consider someone sufficiently well-trained, yet wise enough to understand the value in simplicity, humble enough to listen to the ideas of others and keep learning, and curious enough to actively consult others for dissenting ideas to be one of tomorrow's experts.
In other words, I agree. :P
That's actually been my recommendation for a while for high assurance. What you think of it?
Somewhat related anecdote: Trying go get WordPress to adopt a CSPRNG was painful for a year.
Then I started paragonie/random_compat and like 30 other people pitched in to improve it, and then I suggested just using that (so new code can be written against PHP 7's API). And so the problem was solved.
I'd tend to agree that, for security matters, a small team of people focused on success with the knowledge and/or resources they need to execute on their own initiatives gets a better result than a large team with varied interests and use cases.
I'm wondering if Zed would consider say Carmack for example, such a master coder?
"a competition that challenges coders to solve a simple data processing problem by writing innocent-looking C code that is as readable, clear, and seemingly trustworthy as possible, yet covertly implements a malicious function."
Those for whom the name Linus Åkesson is unfamiliar are highly encouraged to visit his site at http://www.linusakesson.net/ --- he has a lot of other interesting articles on programming and the demoscene.
So does he mean that programming/hacking is not about banging a keyboard as fast as possible?/s I wish more people knew that.
The only real alternative would be a a preprocessor define, which is even more "heavyweight". A define written in uppercase might be better if you want to signify that it's something changeable, but the typedef is probably slightly safer.
The real issue here is not the typedef, but the name choice. "float_t" is a reserved name, and it's unlikely to be a good idea to typedef a reserved name. Counter to common practice, all typenames ending with "_t" are actually reserved by Posix[1] and thus arguably should be avoided for user code.
[1] http://www.gnu.org/software/libc/manual/html_node/Reserved-N...
For the winner, perhaps the gcc flag, -Wmissing-prototypes would catch it?
Nope, no warnings at all for spectral_contrast.c with GCC, ICC, or Clang even with "-Wall -Wextra -pedantic". Then I thought to try it on MSVC at http://webcompiler.cloudapp.net/. To my surprise, it caught it pretty clearly with /W4:
main.cpp(11): warning C4244: '/=': conversion from 'double'
to 'float_t', possible loss of data
With that hint, I searched for other GCC warnings and found -Wconversion. Indeed, with that (or -Wfloat-conversion) GCC picks up the scent pretty well: http://goo.gl/9xq3fG In function 'void normalize(float_t*, int)':
11 : warning: conversion to 'float_t {aka float}' from
'double' may alter its value [-Wfloat-conversion]
ICC gives an excellent error message with -Wconversion also, perhaps the clearest of the bunch: http://goo.gl/cjXLjq warning #2259: non-pointer conversion from "double" to
"float_t={float}" may lose significant bits
for(i = 0; i < length; i++) v[i] /= magnitude;
Clang remained silent with all the options I tried, but perhaps I missed the right one. $ clang -Wall -Weverything -pedantic -c -o spectral_contrast.o spectral_contrast.c
spectral_contrast.c:16:8: warning: no previous prototype for function 'spectral_contrast' [-Wmissing-prototypes]
double spectral_contrast(float_t *a, float_t *b, int length) {
^
1 warning generated.Clang does give a warning with -Weverything, but I don't understand what it means: http://goo.gl/M9qjmx
13 : warning: no previous prototype for function spectral_contrast' [-Wmissing-prototypes]
double spectral_contrast(float_t *a, float_t *b, int length) {
It gives the same warning if I change all the float_t's to float, or if I change all the float_t's to double, so I think it's not actually useful or relevant.The warning occurs because the function is not static — and therefore callable by other modules. Since it's missing a forward definition (a previous prototype), those modules must blindly declare the prototypes themselves… and their prototypes can get out of sync with the actual definition. That's what's happening here. `match.h` has the forward prototype, but it's very subtly different from the definition. Were match.h included, there'd be a much more glaring warning (or maybe even error).
for(i = 0; i < length; i++) sum += a[i] * b[i];
^
I managed to hide the error if return values, which are double, are replaced with float_t. I believe in that case the bug stays in, but -Wconversion doesn't detect it.Of course the warning can always be silenced by doing something like:
for(i = 0; i < length; i++) sum += ( double )( a[i] * b[i] );
and adding a misleading comment about the explicit cast.Reading through the source made me look twice though, as I am used to writing C++ so seeing variables defined but not initialised, non-const array starting points as parameters with a separate length parameter (instead of just a reference to a container or a const reference to enforce read-only nature), memcpy instead of copy constructors or copy assignment operators.
Basically, it made me realise how impossible I would find it to write good C!
Really clever entry though, very impressive. I spotted all the issues I mentioned above, looking for mistakes in them and completely missing the actual problem.
That was my thought when the comparison was with Turbo Pascal 6.0.
Luckily in the same year I got Turbo C 2.0, someone made me aware that the school also had the newly released Turbo C++ 1.0 available.
Since then, using C instead of C++ or better alternatives, only when I didn't have an option to do so.
I presumed it was simply going to try to slip in a 'float' for a 'float_t' and hope it wasn't noticed, although it seemed unlikely to be a winning strategy.
One other thing that seemed odd was the continued use 'double' after the typedef. I wonder if there's a way to make it work where all the usages are replaced by 'float_t'.
Yes, in fact you don't have to change anything else. The trick is that on x86-64 float is promoted to double for argument passing, so the mismatch in the return type on spectral_contrast has no effect.
The Linux name is a play on Linus' name.
The Å in Åkesson can be typed on a US keyboard by hitting alt+a. To make ä & ö you'd hit `alt+u a` and `alt+u o`. To make a ø, which is the Norwegian/Danish way to say ö, you type `alt-o`.
EDIT: the keyboard things are on a US layout on a Mac. For a standard keyboard it might be the same, or not. I don't know...
Torvalds is from the Swedish-speaking minority in Finland.
On my phone or I'd provide the equivalents.
Does this mean that you can't hold down a key to produce multiple copies of the same letter?
Å - 0197
å - 0229
Ä - 0196
ä - 0228
Ö - 0214
ö - 0246
From http://fsymbols.com/keyboard/windows/alt-codes/list/