Hacker News new | past | comments | ask | show | jobs | submit login

Yes, that's a typo. Sorry.

(Lesson learned: LaTex is not the best language to write code in.)

DO: Do what Bruce Eckel does, and have all code in a publication run through automated tests before releasing it. ;-). And... you're welcome?


      x |= MAC received[i] − MAC computed[i];
Is making me twitchy, I mean I'm sure we're on two's complement machines and there is no C compiler in the world where those two could be unequal but still subtract to zero* , but still, how about one of

      x |= (MAC received[i] != MAC computed[i]);
      x |= (MAC received[i] ^ MAC computed[i]);
Otherwise, Good stuff!

* Possible break: If we have a separate sign bit, then we might have 0 and -0, which would subtract to give 0. Don't know of any machine/compiler that does that though.

I always use ^ when I write this code, but that made LaTex unhappy, so I switched to subtraction instead for the talk.

Did you try to escape your ^ like \^?

I think so. It was something like 4 AM at the time, so it's possible that I didn't escape it correctly.

Your != proposed change likely results in a branch, which is what we're trying to avoid. The ^ version is fine, but the original subtraction is too as long as they're unsigned.

Are you sure? All architectures I am aware of have mechanisms to do this in a branchless way. On my machine: int main(int argc, char argv) { int x = 0; x |= (argc != 1); return x; }

Relevant portion of assembly (no optimizations): cmpl $1, -20(%rbp) setne %al movzbl %al, %eax orl %eax, -4(%rbp)

Most other architectures have one of: 1) condition codes that you can use to predicate an "or $r1, $r1, 1" (e.g., ARM) 2) compare instructions that put a 1 or a 0 in a result register, which can be directly ORed in. (e.g., MIPS)

Of course, that code only works if you are either not writing in C89 or if your compiler and ISA conspire to always return exactly one from true boolean expressions. It is my understanding that the C89 standard only requires "nonzero," so you might need "a |= (b != c) ? 1 : 0;*" instead.

YMMV depending on compiler and architecture, but the 2 or 3 platforms I tried without passing any opti flags were branchless.

Test program:

I wrote about this mistake before. Developers see a single-line RHS expression and think it evaluates without branching.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact