top | item 11655220

(no title)

dsfuoi | 9 years ago

It's just one line. Put this before the loop if the code logically shouldn't trigger this.

  assert( B < B_TYPE_MAX - 4 );
Or use an if statement if it could trigger at runtime.

Also the code is clearer on intent.

discuss

order

pcwalton|9 years ago

You misunderstood the problem. The problem isn't that programmers can't write loops that are easy to optimize. It's rather that, in practice, they don't write loops that are easy to optimize. That's ultimately a problem with the C language.

dsfuoi|9 years ago

If the loops can be written and the programmers don't write them, the problem is with the language!?

No, it's pretty clear where the problem is with C, programmers.

haberman|9 years ago

Can assert() actually function this way? Can you use assert to tell the optimizer it can assume something is true?

I've noticed that memcpy(x, y, 4) on x86 can generate very efficient code (register move), but on ARM it expands to something much more verbose because the addresses might not be aligned.

Could this effectively function as a way of promising to the compiler that the addresses are aligned?

    void move4_aligned(void *dst, const void *src) {
      assert(((uintptr_t)dst & 0x3) == 0);
      assert(((uintptr_t)src & 0x3) == 0);
      memcpy(dst, src, 4);
    }

quotemstr|9 years ago

> Can assert() actually function this way? Can you use assert to tell the optimizer it can assume something is true?

Trivially.

  #ifdef NDEBUG
  # define assert_and_assume(cond) if(!(cond))     
    __builtin_unreachable((cond))
  #else
  # define assert_and_assume assert
  #endif

nkurz|9 years ago

Can assert() actually function this way? Can you use assert to tell the optimizer it can assume something is true?

Yes, but it would have the potentially surprising behavior that compiling your release version with -DNDEBUG might slow it down. We ran into this a couple years ago: https://plus.google.com/+DanielLemirePhD/posts/BTSams19Ero

Recent compilers support some extensions that can do it better. GCC and CLang use __builtin_assume_aligned(), and ICC uses __assume_aligned() (haven't tested the synonym).