[freebsd] printf в clang

Valentin Nechayev netch at netch.kiev.ua
Fri Dec 31 11:53:35 EET 2021


hi,

 Fri, Dec 31, 2021 at 08:20:44, spell wrote about "Re: [freebsd] printf в clang": 

> > Именно что если в 32 битах, то всё логично, потому что:
> > 1. При передаче в переменном наборе аргументов (как printf) происходит
> > расширение всех целочисленных типов, которые у́же int, к int, а более
> > широкие не меняются.
> > 2. Соглашение о вызове предусматривает передачу всех аргументов на
> > стеке. Соответственно в позиции начала переменной области аргументов
> > укладывается: 03 00 00 00 02 00 00 00 (bv) 6f 00 00 00 (cid).
> > 3. printf согласно формату %ld извлекает long, который в этом режиме
> > 32 бита (равен int). Извлекается 03 00 00 00 (значение 3).
> > Второй %ld извлекает 02 00 00 00 (значение 2).
> 
> Так и предположила.
> Собственно, вопрос - это считается за баг, или "сам виноват"?

Сам виноват. В стандарте описано явно, что в функциях с переменным
числом аргументов вызывающий должен обеспечить соответствие типов
ожидаемым, с учётом автоматического неявного расширения.

> Варнинг, конечно, это хорошо, но и обработка ситуации тоже важна.
> Вот например такой код:
> 
> printf("%ld %ld\n", bv, cid, cid);
> 
> выдаст варнинг насчет лишнего аргумента, но значение cid не выведет,
> хотя в стеке аргументов место для этого второго cid есть.

Да, потому что не сказано его печатать. А если будет, наоборот, лишний
%ld без параметра - выведется что-то со стека (условно, мусор).

В C++ это фиксили в основных средствах (iostreams, boost::format...) -
там есть контроль типов и параметры ввода-вывода устанавливаются во
время компиляции. В C такое как-то не завезли.


-netch-


More information about the freebsd mailing list