вопрос о несовместимых спецификаторах формата printf - PullRequest
5 голосов
/ 01 апреля 2009

Я просто просматривал справочную страницу для printf, и со мной что-то произошло. Мне было интересно, есть ли здесь «юристы по языку», которые могли бы ответить на относительно простой вопрос: -P.

Таким образом, модификатор 't' определяется как

следующее целочисленное преобразование соответствует аргументу ptrdiff_t.

Так что же должно произойти , если вы объедините это с целым числом без знака? Ясно, что все o, u, x и X предназначены для интерпретации как значения без знака, в то время как d и i подписаны.

Аналогично, существуют подписанные / неподписанные версии для всех модификаторов (int / unsigned int, size_t / ssize_t и т. Д.), Кроме ptrdiff_t.

На практике ничего плохого не происходит, поскольку неподписанные версии типов занимают столько же места, что и подписанные версии. Таким образом, правая часть байтов выталкивается из стека.

Таким образом, ничего «плохого» не происходит, на самом деле, печатается ожидаемое значение для всех проверенных вещей, кроме «INT_MIN» (при условии, что sizeof(int) == sizeof(ptrdiff_t).

printf("%tu %td\n", INT_MIN, INT_MIN);

печать

2147483648 -2147483648

в 32-битной системе.

Есть ли у стандарта мнение по этому поводу? Я полагаю, что ответом будет «неопределенное поведение». Но я решил спросить;).

1 Ответ

3 голосов
/ 01 апреля 2009

Здесь нечего видеть. Код, который вы написали, является законным.

Просто некоторые факты о том, почему:

  • все целые типы со знаком имеют беззнаковые аналоги с одинаковыми требованиями к размеру / выравниванию
  • ptrdiff_t предписано стандартом как целочисленный тип со знаком. Следовательно, у него есть неподписанный близнец. (На самом деле, аналогичная логика применима и к size_t - ssize_t - это не C, а POSIX)
  • спецификатор длины t должен работать с типами d, i, o, u, x, X
...