Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



Yup, 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?


Definitely 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


> b) NULL is not a useful macro. For example, > printf ("%p", NULL); > can have unexpected results.

How do you figure?


According 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 *)


I 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.


Maybe arch with variable width pointer types like some embedded platforms?


How 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).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: