Skip to content

Instantly share code, notes, and snippets.

@o11c
Last active May 10, 2017 19:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save o11c/0f117636d6c8873d5cc6f63347ee4fdd to your computer and use it in GitHub Desktop.
Save o11c/0f117636d6c8873d5cc6f63347ee4fdd to your computer and use it in GitHub Desktop.
Portable C89 implementation of signed/unsigned integer dispatch.
/*
* Portable C89 implementation of signed/unsigned integer dispatch.
*
* Written by Ben Longbons <b.r.longbons@gmail.com>
* The latest version of this file may be found at:
* https://gist.github.com/o11c/0f117636d6c8873d5cc6f63347ee4fdd
*
* Dedicated to the public domain via CC0 on 2017-05-10, in the USA.
* See https://creativecommons.org/publicdomain/zero/1.0/
*/
/*
* C99 is just used in the main() function for testing.
*/
#define _ISOC99_SOURCE
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
/*
* Works *without* multiple evaluation of macro arguments.
* But do note that integer promotion still occurs - but that's safe.
*/
#define zero_of_type(val) (0 ? (val) : 0)
#define maybe_negative(val) (( zero_of_type(val) - 1) < 0)
static void int_str_unsigned(const char *buf, uintmax_t val)
{
__extension__ printf("unsigned: %s = %ju\n", buf, val);
}
static void int_str_signed(const char *buf, intmax_t val)
{
__extension__ printf("signed: %s = %jd\n", buf, val);
}
#define int_str(buf, val) (maybe_negative(val) ? int_str_signed((buf), (val)) : int_str_unsigned((buf), (val)))
/* Bad version: #define int_str(buf, val) (((val) < 0) ? int_str_signed((buf), (val)) : int_str_unsigned((buf), (val))) */
int main()
{
bool once_flag = true;
#define once_reset() (once_flag ? (void)0 : abort(), once_flag = false)
#define once(expr) ((once_flag ? abort() : (void)0), once_flag = true, (expr))
once_reset(); int_str("CHAR_MIN", once((char)CHAR_MIN));
once_reset(); int_str("CHAR_0", once((char)0));
once_reset(); int_str("CHAR_MAX", once((char)CHAR_MAX));
once_reset(); int_str("SCHAR_MIN", once((signed char)SCHAR_MIN));
once_reset(); int_str("SCHAR_0", once((signed char)0));
once_reset(); int_str("SCHAR_MAX", once((signed char)SCHAR_MAX));
once_reset(); int_str("UCHAR_0", once((unsigned char)0));
once_reset(); int_str("UCHAR_MAX", once((unsigned char)UCHAR_MAX));
once_reset(); int_str("SHRT_MIN", once((short)SHRT_MIN));
once_reset(); int_str("SHRT_0", once((short)0));
once_reset(); int_str("SHRT_MAX", once((short)SHRT_MAX));
once_reset(); int_str("USHRT_0", once((unsigned short)0));
once_reset(); int_str("USHRT_MAX", once((unsigned short)USHRT_MAX));
once_reset(); int_str("INT_MIN", once((int)INT_MIN));
once_reset(); int_str("INT_0", once((int)0));
once_reset(); int_str("INT_MAX", once((int)INT_MAX));
once_reset(); int_str("UINT_0", once((unsigned int)0));
once_reset(); int_str("UINT_MAX", once((unsigned int)UINT_MAX));
once_reset(); int_str("LONG_MIN", once((long)LONG_MIN));
once_reset(); int_str("LONG_0", once((long)0));
once_reset(); int_str("LONG_MAX", once((long)LONG_MAX));
once_reset(); int_str("ULONG_0", once((unsigned long)0));
once_reset(); int_str("ULONG_MAX", once((unsigned long)ULONG_MAX));
once_reset(); int_str("LLONG_MIN", once(__extension__ (long long)LLONG_MIN));
once_reset(); int_str("LLONG_0", once(__extension__ (long long)0));
once_reset(); int_str("LLONG_MAX", once(__extension__ (long long)LLONG_MAX));
once_reset(); int_str("ULLONG_0", once(__extension__ (unsigned long long)0));
once_reset(); int_str("ULLONG_MAX", once(__extension__ (unsigned long long)ULLONG_MAX));
return 0;
}
CFLAGS = -std=c89 -g -O2 -Wall -Wextra -pedantic
override CFLAGS += -Wno-type-limits
test: int-str
./int-str
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment