How do you printf _ExtInt without using casts?

716 Views Asked by At

I was wondering how you could printf _ExtInts in clang without using casts. Something like this:

#include <stdio.h>

int main() {
    _ExtInt(13) foo = 100;
    printf("%???", foo);
}

With casts, it would look like this (this is not what I want):

#include <stdio.h>

int main() {
    _ExtInt(32) foo = 100;
    printf("%d", (int) foo);
}
2

There are 2 best solutions below

8
Jonathan Leffler On

The _ExtInt types are a new feature in Clang (LLVM) as described at The New Clang _ExtInt Feature Provides Exact Bitwidth Integer Types, published 2020-04-21 (3 days ago as I type).

If _ExtInt(32) is a 32-bit signed integer type and int is a 32-bit signed integer type, then you can use %d and no cast in both calls to printf(). The arguments after the format are subject to the integer promotion rules, so I expect that both _ExtInt(13) and _ExtInt(32) would be converted to int as they are passed to printf(), so the correct conversion specifier is %d.

If you use bigger types, up to _ExtInt(64), you can probably use %lld on any machine (or %ld on a 64-bit machine). If you go bigger than that, you are on your own; you need an implementation of printf() that knows how to handle _ExtInt types, and that will probably have notations in the format that allow for the length to be specified. For example, hypothesizing wildly, it might support %<700>d for a signed _ExtInt(700).

2
chux - Reinstate Monica On

Use a wide type by forming a long product. int may be 16-bit. long is at least 32. long long is at least 64.

_ExtInt(13) foo1 = 100;
printf("%d\n", 1 * foo);
// or
printf("%d\n", 0 + foo);

_ExtInt(32) foo2 = 100;
printf("%ld\n", 1L * foo);
// or
printf("%ld\n", 0L + foo);