Is there any way to tell the compiler that an integer type need not be truncated?

136 Views Asked by At

take this code snippet

void thing(signed short ss);
void test(int i){
    thing((signed short)i);
}

both gcc and clang generate

        movswl  %di, %edi
        jmp     thing(int)

however I know that the argument is between -32768 and 32767. And I can't change any of the argument types. So that movswl is basically a nop. In fact, gcc does a truncation every time it recieves a short argument. So it actually truncates it twice per in some function calls.

ideally I'd want a sort of assert_within_bounds_cast function that's sort of a cross between reinterpret_cast and bit_cast that basically says "don't worry about truncating, just use whatever register size is most convenient". I tried building it myself using __builtin_unreachable() and reinterpret_cast but it didn't work consistently and sometimes made things worse.

1

There are 1 best solutions below

1
ti7 On

If you can't change the argument types to test, you're stuck - callers can't possibly know that your function expects signed short when it accepts an int (which might be wider, but not always), and callers of the function may pass it an int outside of your control

Is it possible you can overload the function?

void thing(signed short ss);
void test(int i){
    // consider asserting here too
    thing((signed short)i);
}
void test(signed short i){
    thing(i);
}

Finally, watch out when analyzing the results of really trivial / non-representative cases - if you really have void functions without a mutable arg, they may be completely dropped when (further) optimizations are applied, so you can't easily have a case where both full optimizations run (which may discover and fix your case) and the function(s) exist at all!