Преобразование типов в printf

erotic

Наверное связано с этой темой:
Вопрос вот в чем: printf - функция с переменным числом аргументов, и тип своих аргументов она определяет по формируемой пользователем строке формата. При этом printf по формату "%f" нормально выводит как double (8 байт так и float (4 байта). Как это происходит? Я могу лишь предположить, что надо printf'ами компилятор специально колдует, что не честно.

kokoc88

Я могу лишь предположить, что надо printf'ами компилятор специально колдует, что не честно.
Он колдует над ...

Sun-jwer

Я могу лишь предположить, что надо printf'ами компилятор специально колдует, что не честно.
а там правильно не %lf ?
можно просто переменную приводить к типу дабл и печатать. т.е. если она флоат то приводим к дабл и печатаем, нет - просто печатаем.

Dasar

При этом printf по формату "%f" нормально выводит как double (8 байт так и float (4 байта). Как это происходит? Я могу лишь предположить, что надо printf'ами компилятор специально колдует, что не честно.
зачем для этого компилятор?
внутри printf проверяем подходит ли следующие 4 байта под стандартный float, или следующие 8 байт под стандартный double.
что подошло, то и выводим.

okis

А что значит «подходит»? Там разве не всё пространство значений используется?

erotic

А что значит «подходит»? Там разве не всё пространство значений используется?
Ага, тот же вопрос.

kokoc88

или следующие 8 байт
И выпадаем в Access Violation. В общем-то компилятор колдует над "..." и приводит float к double.

erotic

а там правильно не %lf ?
Не, %lf вроде long double.
можно просто переменную приводить к типу дабл и печатать. т.е. если она флоат то приводим к дабл и печатаем, нет - просто печатаем.
Можно, но зачем? printf сам с этим прекрасно справляется, я хочу узнать, как.

kokoc88

я хочу узнать, как
http://msdn.microsoft.com/en-us/library/fc9te331(VS.80).aspx

erotic

В общем-то компилятор колдует над "..." и приводит float к double.
Только для printf или для любой функции с "..."?

erotic

http://msdn.microsoft.com/en-us/library/fc9te331%28VS.80%29....
Какая связь передачи параметров в функцию и продвижениями?

kokoc88

Какая связь передачи параметров в функцию и продвижениями?
Гугл что, отменили? Я ответил на все вопросы ещё во втором посте этой темы.
http://msdn.microsoft.com/en-us/library/zaawxy2f(VS.80).aspx

erotic

http://msdn.microsoft.com/en-us/library/zaawxy2f(VS.80).aspx
Ты мне чушь какую-то присылаешь.
Ни по одной из твоих ссылок не написано, что аргументы продвигаются до других типов при передачи их в "...".

kokoc88

Ни по одной из твоих ссылок не написано, что аргументы продвигаются до других типов при передачи их в "...".
Function declarations in which the last member of argument-declaration-list is the ellipsis (...) can take a variable number of arguments. In these cases, C++ provides type checking only for the explicitly declared arguments. You can use variable argument lists when you need to make a function so general that even the number and types of arguments can vary. The printf family of functions is an example of functions that use variable argument lists.

When arguments of type char are passed as variable arguments, they are converted to type int. Similarly, when arguments of type float are passed as variable arguments, they are converted to type double. Arguments of other types are subject to the usual integral and floating-point promotions. See Integral Promotions for more information.

erotic

Да, я уже заметил, сорри, туплю.

Dasar

И выпадаем в Access Violation. В общем-то компилятор колдует над "..." и приводит float к double.
это если алгоритм проверяет обе ветки
а если он проверяет 8 байт, только если ему не понравились 4 - то никакого access violation не будет

Dasar

When arguments of type char are passed as variable arguments, they are converted to type int. Similarly, when arguments of type float are passed as variable arguments, they are converted to type double. Arguments of other types are subject to the usual integral and floating-point promotions. See Integral Promotions for more information.
хитро...

Andbar

access violation
Чтобы устроить AV на стеке, надо передать очень-очень много параметров.
По поводу сабжевого вопроса: точно помню, что когда-то ваткомовский компилятор для даблов требовал %lf, иначе выводилась абракадабра.

tamusyav

И не только ваткомовский, кажется. Может более ранний стандарт библиотеки предполагал такое поведение, то есть, продвижения типов в описанной выше ситуации не было?

elenangel

Чтобы устроить AV на стеке, надо передать очень-очень много параметров.
... поэтому так делать можно. а потом выходит новая ось, которая контролирует что передавалось в стек и все программы которые так делали начинают падать по ошибке общей защиты.

Andbar

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

Ivan8209

>> ... поэтому так делать можно. а потом выходит новая ось,
>> которая контролирует что передавалось в стек и все программы
>> которые так делали начинают падать по ошибке общей защиты.
> в общем-то ты прав: ПО должно вести себя корректно в не
> зависимости от того, на сколько это контролируется
"Wir muessen nur storben." Это не такой простой вопрос.
Конечно, это хорошо, если программа делает как можно меньше
допущений, но это совсем не всегда приводит к эффективному коду.
---
"Для того, чтобы не пройти мимо цели, иногда необходимо пойти ко дну."

Serab

Да, как раз сейчас приходится много работать с кодом, который должен работать очень много где. И приходится отказываться от огромного количества привычных вещей. Вон, в одном треде так вообще глаза вылупили и чуть не прибили. Так это для уже существующих осей, платформ и компиляторов, а тут расчет на какие-то, которые потом придумают. В общем загоняться не стоит :grin:

evolet

Чтобы устроить AV на стеке, надо передать очень-очень много параметров.
?
а физ страницы для стека разве ось не выделяет динамически?

Andbar

а физ страницы для стека разве ось не выделяет динамически?
одна проблемка: при просмотре параметров функции с переменным числом аргументов, ты рискуешь залезть не на неиспользуемую область адресов стека, а на данные, которые были положены в стек до вызова функции и что-то мне подсказывает, что этих данных гораздо больше чем два указателя возврата, соответственно залезть за начало стека будет сложно.
Оставить комментарий
Имя или ник:
Комментарий: