Clang - Как вы печатаете _ExtInt без использования приведений? - PullRequest
2 голосов
/ 25 апреля 2020

Мне было интересно, как вы можете printf _ExtInt с в лягушке, не используя броски. Примерно так:

#include <stdio.h>

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

С приведением типов это будет выглядеть так (это не то, что я хочу):

#include <stdio.h>

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

Ответы [ 2 ]

2 голосов
/ 25 апреля 2020

Типы _ExtInt - это новая функция в Clang (LLVM), как описано в Новая функция Clang _ExtInt обеспечивает точные целочисленные битовые типы , опубликовано 2020-04-21 (3 дня a go, как я набираю).

Если _ExtInt(32) - это 32-разрядный целочисленный тип со знаком, а int - это 32-разрядный целочисленный тип со знаком, то вы можете использовать %d и не приводить в обоих случаях. звонки на printf(). Аргументы после формата подчиняются правилам целочисленного продвижения, поэтому я ожидаю, что и _ExtInt(13), и _ExtInt(32) будут преобразованы в int, поскольку они передаются в printf(), поэтому правильный спецификатор преобразования - %d .

Если вы используете более крупные типы, вплоть до _ExtInt(64), вы, вероятно, можете использовать %lld на любой машине (или %ld на 64-битной машине). Если вы go больше этого, вы сами по себе; вам нужна реализация printf(), которая знает, как обрабатывать типы _ExtInt, и, вероятно, будет иметь нотации в формате, позволяющем указывать длину. Например, дико выдвигая гипотезу, он может поддерживать %<700>d для подписанного _ExtInt(700).

1 голос
/ 25 апреля 2020

Используйте широкий тип, формируя long продукт. int может быть 16-разрядным. long - минимум 32. long long - минимум 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);
...