On Tue, Jun 14, 2011 at 05:59:47PM +0300, Dimitrios Apostolou wrote: > >>static void puthexl (unsigned long value, FILE *f) > >>{ > >> static char hex_repr[16]= {'0', '1', '2', '3', '4', '5', '6', '7', > >> '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; > >> static char buf[2 + 2*sizeof(value)]= "0x"; > >> int i; > >> int j= 2; > >> > >> for (i = 8*sizeof(value)-4; i>=0; i-= 4) > >> { > >> char c= (value >> i) & 0xf; > >> if (c!=0 || j>2) > >> { > >> buf[j]= hex_repr[(int)c]; > > > >Why not just "0123456789abcdef"[c] instead > > Code just looked more beautiful, that's all. :-)
Well, I find that two lines hex_repr initializer much less readable. Anyway, what glibc does is: static inline char * __attribute__ ((unused, always_inline)) _itoa_word (unsigned long value, char *buflim, unsigned int base, int upper_case) { const char *digits = (upper_case ? _itoa_upper_digits : _itoa_lower_digits); switch (base) { # define SPECIAL(Base) \ case Base: \ do \ *--buflim = digits[value % Base]; \ while ((value /= Base) != 0); \ break SPECIAL (10); SPECIAL (16); SPECIAL (8); default: do *--buflim = digits[value % base]; while ((value /= base) != 0); } return buflim; } and as it is called with constant base and constant upper_case, the switch/modulo/division is optimized. You'd use it as: void puthexl (unsigned long value, FILE *f) { char buf[2 + CHAR_BIT * sizeof (value) / 4]; if (value == 0) putc ('0', f); else { char *p = buf + sizeof (buf); do *--p = "0123456789abcdef"[value % 16]; while ((value /= 16) != 0); *--p = 'x'; *--p = '0'; fwrite (p, 1, buf + sizeof (buf) - p, f); } } If the number is small, which is the common case, this will iterate just small number of items instead of always 16 times. Anyway, generally, I wonder if replacing lots of fprintf calls won't lead to less readable and maintainable code, if many of the fprintfs will need to be replaced e.g. by two separate calls (one fwrite, one puthexl or similar). Plus, what I said on IRC, regarding transformation of fprintf calls to fwrite if there are no %s in the format string, we should leave that to the host compiler. It actually already does such transformations for fprintf, but in this case we have fprintf_unlocked due to system.h macros, and that isn't optimized by gcc into fwrite_unlocked. That IMHO should be fixed on the host gcc side though. Jakub