3 ms·
A note of warning: memcpy and memmove are not optimized away on msvc and icc. That is, every call to those functions is always a function call. Contrast to gcc
by Asooka 8y ago
A note of warning: memcpy and memmove are not optimized away on msvc and icc. That is, every call to those functions is always a function call. Contrast to gcc and clang which always inline those calls even in no-optimizations builds. To do away with memcpy calls, you can use this:
_Bool check_ip_header_sum(const char* p, size_t size) {
struct Chunk { char arr[4]; };
const Chunk* chunks =
(const Chunk*)p;
union {
Chunk chunk;
uint32_t n;
} helper;
uint64_t sum=0;
for (size_t i=.....) {
helper.chunk=chunks[i];
sum+=helper.n;
}
........
}
Technically speaking, going through a union like that is also undefined behaviour, however this is used everywhere in the Linux kernel, so both GCC and Clang will support it indefinitely, while MSVC is very conservative anyway, so you can rely on it supporting it as well. There is pretty much zero reason for the compiler to produce garbage code here. Note also that you can't cast p to the union type directly, because the union type has uint32_t alignment, so you have to do it this way. And you have to go through a struct, because you can't copy-assign arrays... Anyway the union+chunk trick seems more readable to me as well, but that's down to personal preference.
- Karliss 8y agoWhen was the last time you checked that msvc and icc always use a function call form memcpy? At least the latest versions of msvc and icc can replace memcpy with appropriate move instruction. You can see here https://godbolt.org/z/BX0Wya https://godbolt.org/z/BX0Wya that msvc 2017, msvc 2015, icc 18.0 and even icc 13.0.1 used a mov instruction for memcpy to uint32 instead of function call.
- userbinator 8y agoI believe even MSVC6 will inline memcpy() (and a few others), but it has to be enabled with one of the optimisation switches (intrinsic functions.)
- Asooka 8y agoOk, I stand corrected. However, at lower optimisation levels they do not inline memcpy calls, which might matter for you. It's never fun if the debug build is 10 times slower in a hot function...
- xenadu02 8y agoIIRC the latest C standards adopted the union trick for type punning; it is the only correct way to access floating-point as int, or create an array of function pointers of different types. (The latter is not something I've seen any compiler ever exploit though)
- saagarjha 8y ago> it is the only correct way to access floating-point as int Well, other than memcpy. And it's kinda sketchy in the way that they did it: it was a tacked-on footnote in the C99 standard retained through to C11. > create an array of function pointers of different types Well, void * * or char * * (spaces so Hacker News doesn’t eat it) would do just as well…
- Asooka 8y agoWhat about the latest C++ standards :) ?