[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