From 66507906673bc6159d5d620414479954c9c21c24 Mon Sep 17 00:00:00 2001 From: Yorhel Date: Sun, 8 Nov 2020 15:34:58 +0100 Subject: Use reinterpret-casting in yxml_setchar() This avoids a memcpy() when the compiler doesn't optimize it. I initially avoided doing this out of fear for triggering UB and causing optimizing compilers to optimize the code away, but I believe this is actually safe when the types involved are (unsigned) chars. --- yxml.c | 9 ++------- yxml.c.in | 9 ++------- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/yxml.c b/yxml.c index 10f88dc..23d04a9 100644 --- a/yxml.c +++ b/yxml.c @@ -116,14 +116,9 @@ typedef enum { #define INTFROM5CHARS(a, b, c, d, e) ((((uint64_t)(a))<<32) | (((uint64_t)(b))<<24) | (((uint64_t)(c))<<16) | (((uint64_t)(d))<<8) | (uint64_t)(e)) -/* Set the given char value to ch (0<=ch<=255). - * This can't be done with simple assignment because char may be signed, and - * unsigned-to-signed overflow is implementation defined in C. This function - * /looks/ inefficient, but gcc compiles it down to a single movb instruction - * on x86, even with -O0. */ +/* Set the given char value to ch (0<=ch<=255). */ static inline void yxml_setchar(char *dest, unsigned ch) { - unsigned char _ch = ch; - memcpy(dest, &_ch, 1); + *(unsigned char *)dest = ch; } diff --git a/yxml.c.in b/yxml.c.in index cd73e9e..216b3f6 100644 --- a/yxml.c.in +++ b/yxml.c.in @@ -48,14 +48,9 @@ typedef enum { #define INTFROM5CHARS(a, b, c, d, e) ((((uint64_t)(a))<<32) | (((uint64_t)(b))<<24) | (((uint64_t)(c))<<16) | (((uint64_t)(d))<<8) | (uint64_t)(e)) -/* Set the given char value to ch (0<=ch<=255). - * This can't be done with simple assignment because char may be signed, and - * unsigned-to-signed overflow is implementation defined in C. This function - * /looks/ inefficient, but gcc compiles it down to a single movb instruction - * on x86, even with -O0. */ +/* Set the given char value to ch (0<=ch<=255). */ static inline void yxml_setchar(char *dest, unsigned ch) { - unsigned char _ch = ch; - memcpy(dest, &_ch, 1); + *(unsigned char *)dest = ch; } -- cgit v1.2.3