4 ms·
Real world things in C that may bite you: (a) char may be signed or unsigned so char a, b; ... short c = (short (a) << 8 | b); will not work to constru
by cjensen 10y ago
Real world things in C that may bite you:
(a) char may be signed or unsigned so
char a, b;
...
short c = (short (a) << 8 | b);
will not work to construct a 16-bit value from two 8-bit values.
(b) NULL is not a useful macro. For example,
printf ("%p", NULL);
can have unexpected results.
Those things mentioned in the article? Outside of DSPs and GPUs, you can ignore them.
- problems 10y agoYup, I deal with the unsigned char issue at work all the time, I've got a pile of code with casts to unsigned all over the place due to decoding some legacy data formats. I'm not sure what the cleanest way to fix it is, but I find myself writing nasty stuff like: (((short)((unsigned char)a)) << 8) Which works but goddamn is it ever hard to read. Bracket highlighting makes it just bearable. Fortunately I've abstracted this kind of stuff out as much as possible so I only have it in a few places, but it still bites me in the ass sometimes. Curious if anyone has a cleaner way of expressing this?
- cjensen 10y agoDefinitely use the new stdint.h types[1]. That will make your intent a lot clearer. Also consider creating some macros for all common operations (like creating a uint32_t out of four uint8_t). [1] http://en.cppreference.com/w/c/types/integer http://en.cppreference.com/w/c/types/integer
- loeg 10y ago> b) NULL is not a useful macro. For example, > printf ("%p", NULL); > can have unexpected results. How do you figure?
- cjensen 10y agoAccording to the fine standard, an implementation may #define NULL as either #define NULL ((void *) 0) or just plain #define NULL 0 The latter works correctly because a literal 0 in pointer context is interpreted by the compiler as a null pointer. If it is 0, the printf() provides no pointer context, so the 0 is interpreted as an int. That works... poorly if sizeof (int) < sizeof (void *)
- loeg 10y agoI see (C99/C11 §6.3.2.3, #3). So the latter NULL definition only works poorly for variadic functions. Is there any reason for an implementation to elect to use the non-casted version of NULL? It seems like an oversight.
- deleted 10y ago[deleted]
- acveilleux 10y agoMaybe arch with variable width pointer types like some embedded platforms?
- loeg 10y agoHow is integer zero better in that scenario, though? The (void-star)0 pointer can still be cast to the correct type (and will be for everything except variadic functions like printf).