[freebsd] printf в clang
spell at itl.ua
spell at itl.ua
Fri Dec 31 10:20:44 EET 2021
30 декабря 2021 г., 23:39, "Valentin Nechayev" <netch at netch.kiev.ua> написал:
> hi,
>
> Thu, Dec 30, 2021 at 21:15:36, spell wrote about "[freebsd] printf в clang":
>
>> int64_t bv;
>> long cid;
>> bv = ( (int64_t) 1 << 33) + 3;
>> cid = 111;
>> printf("%ld %ldn", bv, cid);
>
> Тут наверно должно было быть \n в конце форматной строки.
опечатка :(
>> clang резонно выдает варнинг о несоответствии типа первого аргумента (%ld вместо правильного %lld).
>
> Компиляция в 32 битах, я так понимаю? Потому что в 64 проблем не
> видно.
да.
>> А вот вывод этой программы менее ожидаем:
>>
>> 3 2
>>
>> Первое число ожидаемо - младшие 4 байта от bv.
>> А второе, вместо значения cid - старшие 4 байта от bv.
>>
>> clang version 10.0.1.
>
> Именно что если в 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 есть.
> В 64 битах проблемы не будет, потому что:
>
> 1. Первые 6 аргументов передаются в регистрах, включая переменные
> аргументы (! - из-за этого va_arg c компанией заметно усложняется).
> Форматная строка будет в rdi, bv - в rsi, cld - в rdx.
> 2. long и long long одинаково имеют 64 бита ширины и передаются
> соответственно в полную ширину регистра.
Спасибо, очень интересно, буду знать!
More information about the freebsd
mailing list