Это зависит от реализации. Один очевидный способ реализовать это будет:
extern char *__isupper;
#define isupper(x) ((int)__isupper[(x)])
Где __isupper
указывает на массив из 0 и 1, определяемый локалью. Однако этот вид техники потерял популярность, поскольку доступ к глобальным переменным в общих библиотеках довольно неэффективен и создает постоянные требования ABI, а также потому, что он несовместим с локальными языковыми стандартами POSIX.
Другой очевидный способ реализовать его в реализациях только для ASCII или UTF-8:
#define isupper(x) ((unsigned)(x)-'A'<='Z'-'A')