(C (and thereby C++ and friends)

C defines signed and unsigned variants of the basic integer types. You apply the unsigned modifier to a type to specifiy that it is, indeed, unsigned. By default all integer types except char are signed; thus you must specify unsigned if you wish them to be so. char may or may not be signed by default, so you also need to specify unsigned if you specifically need this property.

Thus, after taking into account that int is optional, we have these "unsigned types":

  • unsigned char
  • unsigned short int or unsigned short
  • unsigned int or unsigned
  • unsigned long int or unsigned long
  • unsigned long long int or unsigned long long
Additionally, certain types defined in standard header files -- most notably size_t -- are unsigned. Decimal integer literals can be specified unsigned by appending a u.

All unsigned types can only hold values ≥0. Conversion to unsigned is implicit, and can be very dangerous (see below). Unsigned integer operations are considerably simpler than their signed cousins:


Unanticipated conversion to unsigned types is a common cause for security problems. For example, suppose a received packet of data consists of a length (2 bytes) followed by at most 8K of data. One is tempted to write

void *malloc(int);
unsigned char* get_buffer(unsigned char *buf)
  short len;
  unsigned char *ret;         /* No more than 32K read */
  len = buf[0]<<8 + buf[1];
  /* Ensure no buffer overflow */
  if (len > (1<<13))
    return NULL;
  ret = malloc(len);          /* DANGER! */
  memcpy(ret, buf+2, len);
  return ret;
This code checks to see it's not going to be tricked into copying too much data into ret. Unfortunately, the check fails. Suppose shorts are 2 bytes -- a common enough occurrence. If an attacker specifies a buffer of size 0xfffe, then len==-2, and -2<1<<13. We go on to malloc space. But the argument of malloc is really a size_t, and implicit conversion means we ask for 0xfffffffe bytes of memory. Oops.

ANY arithmetic mixing signed and unsigned operands is suspect. Particularly when one of the operands can be controlled from outside the program. Be careful!