Это проблема типа. Если вы приведете 0 к неподписанному, все будет хорошо:
unsigned mask = ~ (unsigned) 0 >> 1;
printf("%u\n", mask);
Редактировать по комментариям: или использовать буквенную запись без знака, что гораздо более кратко. :)
unsigned mask = ~0u >> 1;
printf("%u\n", mask);