Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Преобразование double в __int64


Автор: Katshooter 15.12.2008, 20:28
Приветик всем)))
ПОМОГИТЕ ПЛИЗ!!! 
Нужно преобразовать double в __int64 без потери данных
Явным преобразованием типа: 

Код


__int64 i64;
double d;
i64=(__int64)d;



теряю данные....

может есть какая-нить сишная функция...???

а, еще проблемка, это нада сделать на Си...

Автор: Rififi 15.12.2008, 20:41
Katshooter, 
Нужно преобразовать double в __int64 без потери данных
поясни глубинный смысл этой фразы.

Автор: Katshooter 15.12.2008, 20:49
))) сори, ну например double 12345672903000000+11E (в таком виде приходят данные), 
при при явном приведении получаем 12345672  (а ...903 округляются)

Автор: Rififi 15.12.2008, 20:59
Katshooter, 
у тебя явно имеется талант к исчерпывающему и предельно понятному объяснению, однако. :gigi:

Автор: Void 15.12.2008, 21:06
Кастуя телепатию, предполагаю, что требуется просто положить содержимое double в int64 побитово.
Код
__int64 i;
double d;
...
((double*)&i)* = df;
/* либо */
memcpy(&i &d, sizeof(i));


Хотя бред конечно. Но никакого другого способа всегда сохранить точное значение нет, fixed point тоже не катит.

Автор: Katshooter 15.12.2008, 21:39
спасибо) буду пробовать)))

Автор: mes 15.12.2008, 22:46
Цитата(Void @  15.12.2008,  21:06 Найти цитируемый пост)
Хотя бред конечно. Но никакого другого способа всегда сохранить точное значение нет, fixed point тоже не катит.

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

Добавлено через 6 минут и 33 секунды
Цитата(Katshooter @  15.12.2008,  20:28 Найти цитируемый пост)
Нужно преобразовать double в __int64 без потери данных

во первых int64 не сможет сохранить дробную часть числа, но даже если это не нужно то :
во вторых разброс значений целочисленной части double гораздо больше чем может вместить int64
следовательно решить задачу с вышеозвученным условием не реально.

Автор: Alek86 15.12.2008, 23:03
Цитата(mes @  15.12.2008,  22:46 Найти цитируемый пост)
во вторых разброс значений целочисленной части double гораздо больше чем может вместить int64следовательно решить задачу с вышеозвученным условием не реально.

насколько я понимаюб, человеку нужно сериализовать double
в int64 записать его реально - побитово

а вот как обстоят дела с разным представлением double числа на разных платформах (та даже на 2х exe-шках, собранных разными компиляторами), я не знаю. возможно double там представляется совсем по-разному, и тупое побитовое сохранение не приведет ни к чему хорошему

Автор: mes 15.12.2008, 23:34
Цитата(Alek86 @  15.12.2008,  23:03 Найти цитируемый пост)
насколько я понимаюб, человеку нужно сериализовать double
в int64 записать его реально - побитово

вот этот набросок каста
http://forum.vingrad.ru/index.php?showtopic=239471&view=findpost&p=1721438
"предназначеный" для битового конвертирования с проверкой размера, и он более безопасен чем простое побитовое сохранение,
но код приспособленный под одну платформу не будет компилиться на другой. 
К  тому же его в той же теме и заругали, поэтому желаю 7 раз обдумать прежде чем использовать.




Автор: J0ker 15.12.2008, 23:38
Цитата(Alek86 @  15.12.2008,  23:03 Найти цитируемый пост)
та даже на 2х exe-шках, собранных разными компиляторами

компилятор тут обычно не при чем
числа с ПТ хранятся в формате, пригодном для загрузки в FPU целевой платформы

Автор: mes 15.12.2008, 23:38
Цитата(Katshooter @  15.12.2008,  20:28 Найти цитируемый пост)

а, еще проблемка, это нада сделать на Си... 

на си можно таже сделать подобный макрос который будет проверять размер и предупреждать, если результат не "вписывается" в хранилище.

Автор: J0ker 15.12.2008, 23:41
Цитата(Void @  15.12.2008,  21:06 Найти цитируемый пост)
((double*)&i)* = df;

во-первых d, а не df
во-вторых *((double*)&i)
а в третьих это UB насколько я понимаю

Автор: Earnest 17.12.2008, 17:54
Да чего там, если размер одинаков, просто union - старый сишный метод. 
Код

union DblToInt64
{
   double f; 
   int64   n;
};

Ну и assert на равенство размеров, на всякий случай... 
И нет там никакого UB.

Автор: J0ker 17.12.2008, 20:38
Цитата(Earnest @  17.12.2008,  17:54 Найти цитируемый пост)
И нет там никакого UB. 

3.10/15
Цитата

If a program attempts to access the stored value of an object through an lvalue of other than one of the following
types the behavior is undefined48):
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of
the object,
— an aggregate or union type that includes one of the aforementioned types among its members (including,
recursively, a member of a subaggregate or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
— a char or unsigned char type.

хотя не совсем понятно, что включает в себя "attempts to access" - но, ИМХО, и запись и чтение

Автор: Earnest 18.12.2008, 14:21
Нет, в данном контексте это использование по назначению - т.е. в вычислениях (или в присваивании).
И потом, никто не говорит, что UB - это когда программа падает. Это просто значит, что результат получится неизвестно какой.
Скажем, целая -1, если ее таким образом преобразовать в double становится Not-a-number. И что там в вычислениях получится -  хто знает. 
Например, если сравнивать NAN с любым числом, то результат стабилен (не помню уже true или false), независимо от того, какое число и какое сравнение. С другой стороны - это не раз наблюдаемое мною поведение наверняка является свойством конкретного компилятора или может даже параметров компиляции (release-debug).

А писать-читать в память ты можешь что угодно - была бы память. Это ведь по сути ничем не отличается от memcpy, как предложил Void, только запись яснее (на мой взгляд).  Reinterpret_cast биты не портит... Т.е. если ты запихиваешь, скажем float в LPARAM, чтобы послать сообщение, а потом его оттуда извлекаешь обратной операцией, то все совершенно нормально и легально.

Автор: J0ker 18.12.2008, 18:43
Цитата(Earnest @ 18.12.2008,  14:21)
Нет, в данном контексте это использование по назначению - т.е. в вычислениях (или в присваивании).
И потом, никто не говорит, что UB - это когда программа падает. Это просто значит, что результат получится неизвестно какой.
Скажем, целая -1, если ее таким образом преобразовать в double становится Not-a-number. И что там в вычислениях получится -  хто знает. 
Например, если сравнивать NAN с любым числом, то результат стабилен (не помню уже true или false), независимо от того, какое число и какое сравнение. С другой стороны - это не раз наблюдаемое мною поведение наверняка является свойством конкретного компилятора или может даже параметров компиляции (release-debug).

А писать-читать в память ты можешь что угодно - была бы память. Это ведь по сути ничем не отличается от memcpy, как предложил Void, только запись яснее (на мой взгляд).  Reinterpret_cast биты не портит... Т.е. если ты запихиваешь, скажем float в LPARAM, чтобы послать сообщение, а потом его оттуда извлекаешь обратной операцией, то все совершенно нормально и легально.

вот тут вы совершенно НЕ правы
связано это не с возможностью/невозможностью конкретного преобразования типа, а с оптимизацией
дело в том, что компилятор зачастую не в состоянии отследить алиасинг, что может приводить при оптимизации к сайдэффектам
например следующий код:
Код

long x=5;
*(short *)&x = 10;
printf("%d", x);

без оптимизации может выдавать "10", а с оптимизацией - "5"
если такое случится, и вы посмотрите на оптимизированный ассемблерный код, то сможете заметить странную вещь - printf либо вызывается с константой - совершенно не взирая на реальное значение переменной, либо присвоение происходит после вызова printf
Обсуждение подобного эффекта тут:
http://www.rsdn.ru/Forum/message/2630988.flat.1.aspx

ЗЫЖ да, если что - вышеприведенный пример ессесна не портируем на биг-ендиан будет явная лажа  smile 

Автор: J0ker 18.12.2008, 19:15
да, вот еще
5.17/8
Цитата

If the value being stored in an object is accessed from another object that overlaps in any way the storage of
the first object, then the overlap shall be exact and the two objects shall have the same type, otherwise the
behavior is undefined
.

Автор: Earnest 19.12.2008, 09:27
Речь идет совсем не о том, чтобы преобразовать типы и спать спокойно, а том, чтобы сделать это ВРЕМЕННО.
Если ты собираешься запихнуть double в int64, а потом пользоваться этим int'ом, то да, это не безопасно. Но если int64 использовать как временное хранилище для битов дабла, то ничего с твоим даблом не случится. А твой пример с printf вообще из другой оперы.

Автор: J0ker 19.12.2008, 18:40
ну не знаю... надо анрила спросить... что-то мне кажется формально это подподает под UB

Автор: GoldFinch 19.12.2008, 20:18
где это уже обсуждалось, толко речь шла о float
так вот в переменную размером N байт можно запихнуть любую другую переменную N байт и ничего с ней не случиться.

Автор: UnrealMan 19.12.2008, 20:49
Начнём с того, что в стандарте C++ нету встроенного типа __int64 smile
Далее, т.к. стандарт не обязывает double иметь не более строгие требования к выравниванию, чем __int64, то результат reinterpret_cast-а из __int64 * в double * - unspecified.

Цитата(Earnest @  18.12.2008,  14:21 Найти цитируемый пост)
А писать-читать в память ты можешь что угодно - была бы память. Это ведь по сути ничем не отличается от memcpy

Отличается. На некоторых архитектурах несоблюдение выравнивания приводит к аппаратному исключению. Так что memcpy надёжнее.

Автор: J0ker 19.12.2008, 21:51
UnrealMan, а конкретно под 3.10/15 и 5.17/8 это подпадает?

Автор: UnrealMan 19.12.2008, 23:41
Цитата(J0ker @  19.12.2008,  21:51 Найти цитируемый пост)
а конкретно под 3.10/15 и 5.17/8 это подпадает? 

Под 3.10/15 подпадает, под 5.17/8 - нет.

Автор: Earnest 22.12.2008, 14:22
Цитата(UnrealMan @  19.12.2008,  21:49 Найти цитируемый пост)
Далее, т.к. стандарт не обязывает double иметь не более строгие требования к выравниванию, чем __int64, то результат reinterpret_cast-а из __int64 * в double * - unspecified.

Возможно, в случае с выравниванием и да. Но если я заведу union как предлагала, с обоими этими типами - согласись, все должно быть ок. Хотя, конечно, не факт, что тогда размер юниона будет равен размеру double. Но это уже поддается контролю при сборке.
Кроме того, в жизни такого не встречала (разницы в выравнивании). 
Конечно, на какой-то отдельно взятой и не очень распростаненной платформе - наверное, возможно. Но человек, который на ней програмирует, видимо, должен это знать. А код, который пишется под широко распросраненные платформы вряд ли кто-то расчитывает перенести на какие-то специальные, не прикладывая специальных усилий.
Так что все эти рассуждения очень похожи на теоретическую опастность попасть под кирпич, прогуливаясь по улице.

Автор: UnrealMan 22.12.2008, 15:45
Цитата(Earnest @  22.12.2008,  14:22 Найти цитируемый пост)
Но если я заведу union как предлагала, с обоими этими типами - согласись, все должно быть ок. 

По стандарту нет (см. 3.10/15), но с практической точки зрения, скорее всего, да (если размер double не превышает 64 бит). Другое дело, что непонятно, зачем это нужно - переводить double в __int64 и обратно.

Автор: J0ker 22.12.2008, 23:20
Цитата(UnrealMan @ 22.12.2008,  15:45)
Цитата(Earnest @  22.12.2008,  14:22 Найти цитируемый пост)
Но если я заведу union как предлагала, с обоими этими типами - согласись, все должно быть ок. 

По стандарту нет (см. 3.10/15), но с практической точки зрения, скорее всего, да (если размер double не превышает 64 бит). Другое дело, что непонятно, зачем это нужно - переводить double в __int64 и обратно.

разве это не разрешает делать это через union?:
Цитата

— an aggregate or union type that includes one of the aforementioned types among its members (including,
recursively, a member of a subaggregate or contained union),

Автор: UnrealMan 23.12.2008, 07:44
Цитата(J0ker @  22.12.2008,  23:20 Найти цитируемый пост)
разве это не разрешает делать это через union?

Прочитай внимательно правило целиком.

Автор: Earnest 23.12.2008, 13:16
Если речь о конвертации, а выравнивание неодинаковое (или что-то еще неодинаковое), то обмен через union действительно некорректен - нет гарантии, что все биты будут общими. Корректно только само присваивание. Поскольку union должен быть выделен так, чтобы все комфортно разместились. Я имела в виду именно это.

Цитата(UnrealMan @  22.12.2008,  16:45 Найти цитируемый пост)
дело, что непонятно, зачем это нужно - переводить double в __int64 и обратно. 

Ну, скажем, чтобы передать параметр процедуре, принимающей исключительно int64. Реальный пример  (здесь 
правда речь идет o паре float\DWORD) - послать сообщение с параметром float (притом что там есть только DWORD параметры).

Автор: UnrealMan 23.12.2008, 17:09
Цитата(Earnest @  23.12.2008,  13:16 Найти цитируемый пост)
Ну, скажем, чтобы передать параметр процедуре, принимающей исключительно int64. 

Ну, если процедура изначально написана через ж., и альтернативы её использованию нет, то тут всё понятно. В норме же аргументы неизвестных типов передаются через указатели void * или char *, а не запихиваются в целочисленные объекты.

Автор: GoldFinch 23.12.2008, 19:07
UnrealMan, а нафига создавать переменную в которой будет храниться это значение, вычислять указатель на это значение, если можно просто передать его по значению?

Автор: UnrealMan 23.12.2008, 20:30
Цитата(GoldFinch @  23.12.2008,  19:07 Найти цитируемый пост)
а нафига создавать переменную в которой будет храниться это значение, вычислять указатель на это значение, если можно просто передать его по значению? 

Во-первых, вводить дополнительную переменную нужно только тогда, когда имеется rvalue, к которому нельзя применить операцию взятия адреса.

Во-вторых, объекты целочисленного типа предназначены для хранения целых чисел или наборов флагов, а запихивание в них значений объектов произвольных типов - это использование средств языка не по назначению (точно так же, как забивание шурупов кувалдой - использование кувалды не по назначению). От такого использования страдает как минимум самодокументирумость кода. Этот способ плохо масштабируется. Представим, что спустя некоторое время понадобилось добавить возможность передачи в функцию не только double-значений, но и long double-значений, не вмещающихся в 64 бита. Что делать в таком случае? Придётся передавать значение другим способом. Теряем единообразие.

В-третьих при использовании void * пользователю функции не нужно захламлять код reinterpret_cast-ами для передаваемых аргументов.

Автор: GoldFinch 23.12.2008, 21:00
Цитата(UnrealMan @  23.12.2008,  20:30 Найти цитируемый пост)
Представим, что спустя некоторое время понадобилось добавить возможность передачи в функцию не только double-значений, но и long double-значений, не вмещающихся в 64 бита. Что делать в таком случае? Придётся передавать значение другим способом. Теряем единообразие.

не выходите из контекста задачи
Есть функция которая принимает восемь байт (qwоrd он же int64) мы в эти 8 байт можем запихнуть *чтоугодно* что влезет в 8 байт, а в тех редких случаях когда не влезет, мы передаем указатель на это значение, 8 байт хватит практически на любой указатель.
Так или иначе, вне зависимости от вашего желания такие функции существуют - GetMessage, CreateThread, и т.п.

То что в С++ для такого надо городить reinterpret_cast'ы и другие многобуквенные операторы - это проблема языка С++ которая никак не связана с задачей. Код куда надо передавать эти 8 байт может быть написан на любом ЯП, причем разработчик этого кода мог и не задумываться что ктото будет вызывать этот код в модуле на С++

Автор: J0ker 23.12.2008, 21:46
Цитата(GoldFinch @  23.12.2008,  21:00 Найти цитируемый пост)
То что в С++ для такого надо городить reinterpret_cast'ы и другие многобуквенные операторы - это проблема языка С++ которая никак не связана с задачей.

это проблема интерфейса, сделаного кривыми руками  smile 

Цитата(GoldFinch @  23.12.2008,  21:00 Найти цитируемый пост)
Код куда надо передавать эти 8 байт может быть написан на любом ЯП, причем разработчик этого кода мог и не задумываться что ктото будет вызывать этот код в модуле на С++

а как вы будете этот код вызывать? наверное создадите интерфейс? так вот интерфейс надо делать прямыми руками  smile 

Автор: GoldFinch 23.12.2008, 22:09
ну и как сделать интерфейс к такой функции?

Автор: UnrealMan 23.12.2008, 22:30
Цитата(GoldFinch @  23.12.2008,  21:00 Найти цитируемый пост)
Есть функция которая принимает восемь байт (qwоrd он же int64) мы в эти 8 байт можем запихнуть *чтоугодно* что влезет в 8 байт, а в тех редких случаях когда не влезет, мы передаем указатель на это значение, 8 байт хватит практически на любой указатель.

А не проще ли всегда передавать указатель и не парить пользователю мозги магическим ограничением в 8 байт?

Цитата(GoldFinch @  23.12.2008,  21:00 Найти цитируемый пост)
То что в С++ для такого надо городить reinterpret_cast'ы и другие многобуквенные операторы - это проблема языка С++ 

Можно подумать, в других строготипизированных языках подобные преобразования не нужны.

Автор: J0ker 23.12.2008, 22:34
включаю телепатию и определяю, что это за "такая" функция

Автор: mes 23.12.2008, 22:42
Цитата(J0ker @  23.12.2008,  22:34 Найти цитируемый пост)
включаю телепатию и определяю, что это за "такая" функция 

 smile 
Цитата(GoldFinch @  23.12.2008,  21:00 Найти цитируемый пост)
Так или иначе, вне зависимости от вашего желания такие функции существуют - GetMessage, CreateThread, и т.п.

 smile 

Автор: UnrealMan 23.12.2008, 22:56
А что там не так с этими функциями?

Автор: GoldFinch 23.12.2008, 23:11
Цитата(UnrealMan @  23.12.2008,  22:30 Найти цитируемый пост)
А не проще ли всегда передавать указатель и не парить пользователю мозги магическим ограничением в 8 байт?

если в 95% случаев хватает 8 байт то не проще
более того, не всегда есть возможность передать указатель на переменную вместо значения переменной
например в thread указатель на локальную переменную можно передать только если эа локальная переменная будет существовать,
в sendmessage можно передать указатель только если это сообщение отправляется своему окну, и т.д.

Автор: UnrealMan 23.12.2008, 23:42
Цитата(GoldFinch @  23.12.2008,  23:11 Найти цитируемый пост)
если в 95% случаев хватает 8 байт то не проще

Спорно. Увеличение способов передачи значений предрасполагает к совершению ошибок.

Цитата(GoldFinch @  23.12.2008,  23:11 Найти цитируемый пост)
более того, не всегда есть возможность передать указатель на переменную вместо значения переменной
например в thread указатель на локальную переменную можно передать только если эа локальная переменная будет существовать,
в sendmessage можно передать указатель только если это сообщение отправляется своему окну, и т.д.

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

Код
#include <iostream>

template <class T>
    class Lvalue
{
public:
    Lvalue(const T &t) : m_t(t) {}
    T *operator &() { return &m_t; }
private:
    T m_t;
};
template <class T>
    Lvalue<T> lvalue(const T &t)
        { return Lvalue<T>(t); }

enum FArg { f_arg_pchar, f_arg_double };

void f(const void *p, FArg arg_type)
{
    switch (arg_type)
    {
        case f_arg_pchar:
            std::cout << static_cast<const char *>(p) << std::endl;
            break;
        case f_arg_double:
            std::cout << *static_cast<const double *>(p) << std::endl;
            break;
        default:
            std::cout << "invalid type" << std::endl;
    }
}

int main()
{
    f("some string", f_arg_pchar);
    f(&lvalue(2.7), f_arg_double);
}

Автор: Earnest 24.12.2008, 16:39
UnrealMan, шаблон или прочие ухищрения - это если ты сам проектируешь интерфейс. Тогда да, не надо никаких вывертов и параметры нужны ровно такие, какие нужны.
А вот если ты используешь чужой интерфейс (операционной системы, библиотеки, etc), и он говорит: "только DWORD" или "LPVOID". А тебе нужно float...
Можно и указатель. Если, конечно, мы остаемся в рамках процесса. И при этом нужно гарантировать существование этого объекта (переменной), когда сообщение будет обрабатываться.  А оно вовсе не обязано быть синхронным. И т.д. Короче, ситуаций, когда проще использовать имеющиеся биты и не разводить лишний геморрой ради 4-8 байтов - предостаточно. И никакой это не изврат: ты скажи об этом C-программистам. Просто нужно "уметь их готовить".

Автор: UnrealMan 24.12.2008, 17:26
Цитата(Earnest @  24.12.2008,  16:39 Найти цитируемый пост)
шаблон или прочие ухищрения - это если ты сам проектируешь интерфейс

По этому поводу я уже высказался:

Цитата(UnrealMan @  23.12.2008,  17:09 Найти цитируемый пост)
если процедура изначально написана через ж., и альтернативы её использованию нет, то тут всё понятно


Цитата(Earnest @  24.12.2008,  16:39 Найти цитируемый пост)
И при этом нужно гарантировать существование этого объекта (переменной), когда сообщение будет обрабатываться.  А оно вовсе не обязано быть синхронным.

Что мешает сохранить значение объекта, на который указывает переданный указатель, до возврата управления функцией?

Цитата(Earnest @  24.12.2008,  16:39 Найти цитируемый пост)
И т.д. Короче, ситуаций, когда проще использовать имеющиеся биты и не разводить лишний геморрой ради 4-8 байтов - предостаточно.

Я не знаю ни одной.

Цитата(Earnest @  24.12.2008,  16:39 Найти цитируемый пост)
И никакой это не изврат

Изврат. По причинам, изложенным выше.

Цитата(Earnest @  24.12.2008,  16:39 Найти цитируемый пост)
Просто нужно "уметь их готовить". 

Кто сказал, что из подвальных крыс нельзя приготовить замечательный ужин? Просто нужно "уметь их готовить". Приятного аппетита smile 

Автор: mes 24.12.2008, 17:56
Цитата(UnrealMan @  24.12.2008,  17:26 Найти цитируемый пост)
то из подвальных крыс нельзя приготовить замечательный ужин? 

 smile типа такого ?
http://www.privatwein.de/ebay/Set_Turm_02_PX400x464dpi144.jpg
перевод слов на обложках : филе из крыс, мясо медведя, лягушачьи лапки  smile 

Автор: GoldFinch 24.12.2008, 19:02
Earnest, +1
 
UnrealMan, кроме С++ есть много других языков программирования, с точки зрения которых ваш код на С++ может показаться написанным "через ж."
если вы чегото не знаете это значит что вы это не знаете, а не то что это не существует

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

Автор: Earnest 24.12.2008, 19:31
Цитата(UnrealMan @  24.12.2008,  18:26 Найти цитируемый пост)
если процедура изначально написана через ж., 

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

Цитата(UnrealMan @  24.12.2008,  18:26 Найти цитируемый пост)
Что мешает сохранить значение объекта, на который указывает переданный указатель, до возврата управления функцией?

Какого возврата? Есть асинхронная передача, есть другие процессы... впрочем, уже говорили...
Я могу придумать массу способов как организовать такое безопасное хранение\передачу, если по-другому никак. Но если достаточно запихать float в 4-байтовый int - неужели я буду городить этот огород? Время можно потратить более интересно.

Цитата(UnrealMan @  24.12.2008,  18:26 Найти цитируемый пост)
Я не знаю ни одной.

Цитата(UnrealMan @  24.12.2008,  18:26 Найти цитируемый пост)
Изврат. По причинам, изложенным выше.

Ты на чистом C не программировал никогда?
Можно упираться до посинения: это говорит только о недостатке опыта. Реальный программист работает в реальной ситуации, а не в идеальной. 

Насчет крыс тоже пример так себе. Читаем Фарли Моуэта - ему понравилось. Правда там крысы были не подвальные, а полевые, но с моей точки зрения разница не велика. smile 

Автор: UnrealMan 24.12.2008, 22:40
Цитата(GoldFinch @  24.12.2008,  19:02 Найти цитируемый пост)
UnrealMan, кроме С++ есть много других языков программирования, с точки зрения которых ваш код на С++ может показаться написанным "через ж."

Очень странное заявление.

Цитата(GoldFinch @  24.12.2008,  19:02 Найти цитируемый пост)
если вы чегото не знаете это значит что вы это не знаете, а не то что это не существует

Мне достаточно того, что вероятность существования этого чего-то очень мала (до тех пор, пока кто-либо не предоставит весомых аргументов считать иначе).

Цитата(GoldFinch @  24.12.2008,  19:02 Найти цитируемый пост)
>Что мешает сохранить значение объекта, на который указывает переданный указатель, до возврата управления функцией?
- то что его надо хранить неопределенно долго
- то что значение надо передать в адресное пространство другого процесса

Я не вижу в этих пунктах никаких препятствий.

Цитата(Earnest @  24.12.2008,  19:31 Найти цитируемый пост)
Да вы, батенька, идеалист... 

Ошибаешься. Я материалист smile 

Цитата(Earnest @  24.12.2008,  19:31 Найти цитируемый пост)
Знаешь, сколько код живет?

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

Цитата(Earnest @  24.12.2008,  19:31 Найти цитируемый пост)
Какого возврата?

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

Цитата(Earnest @  24.12.2008,  19:31 Найти цитируемый пост)
Есть асинхронная передача, есть другие процессы

Ну, есть, и что дальше?

Цитата(Earnest @  24.12.2008,  19:31 Найти цитируемый пост)
Но если достаточно запихать float в 4-байтовый int - неужели я буду городить этот огород?

Какой такой огород? Покажи на конкретных примерах, что с чем сравнивается.

Автор: GoldFinch 25.12.2008, 12:53
Цитата(UnrealMan @  24.12.2008,  22:40 Найти цитируемый пост)

>значение надо передать в адресное пространство другого процесса

Я не вижу в этих пунктах никаких препятствий.

чтобы передать указатель в чужое АП этот указатель должен указывать на переменную в чужом АП, а создать переменную в чужом АП - не самая тривиальная задача, более того, зачастую это впринципе невозможно

Цитата(UnrealMan @  24.12.2008,  22:40 Найти цитируемый пост)
Пока функция не вернёт управление, временный объект в примере выше или тем более локальный объект, адрес которого также может быть передан в функцию, гарантированно существует.

асинхронные функции сначала возвращают управление, а потом используют переданные им объекты, вы не знали?

Автор: mes 25.12.2008, 13:00
Цитата(GoldFinch @  25.12.2008,  12:53 Найти цитируемый пост)
асинхронные функции сначала возвращают управление, а потом используют переданные им объекты, вы не знали? 

клонируя при этом нужные из переданных данных, и удаляя последние, когда они им станут не нужны.  (в нормальных условиях)

Автор: GoldFinch 25.12.2008, 14:06
mes, так ведь не везде такое предусмотрено

Автор: UnrealMan 25.12.2008, 14:33
Цитата(GoldFinch @  25.12.2008,  12:53 Найти цитируемый пост)
чтобы передать указатель в чужое АП 

Как реализация межпроцессного взаимодействия связана со способом передачи значения в исходную функцию?

Цитата(GoldFinch @  25.12.2008,  12:53 Найти цитируемый пост)
асинхронные функции сначала возвращают управление, а потом используют переданные им объекты, вы не знали?

Переданные объекты никогда не используются асинхронно, вместо них всегда используются копии объектов.

Автор: GoldFinch 25.12.2008, 15:32
UnrealMan, да с чего вы взяли что всегда копии?
в CreateThread, CreateRemoteThread, SendMessage - не копии

Автор: mes 25.12.2008, 15:43
Цитата(GoldFinch @  25.12.2008,  15:32 Найти цитируемый пост)
SendMessage -

а с чего Вы взяли что эта функция  асинхроннaя ??  (также как и две другие) smile 
Цитата

Sends the specified message to a window or windows. The SendMessage function calls the window procedure for the specified window and does not return until the window procedure has processed the message.

Может имелось ввиду PostMessage. Вот она асинхронная, но и копирует данные. 
Цитата

The PostMessage function places (posts) a message in the message queue associated with the thread that created the specified window and returns without waiting for the thread to process the message.

Автор: GoldFinch 25.12.2008, 16:00
пусть не асинхронная, но в SendMessage параметры сообщения передаются окну без копирования, если в lparam указатель на переменную - никто не скопирует эту переменную

Автор: UnrealMan 25.12.2008, 16:42
Цитата(GoldFinch @  25.12.2008,  15:32 Найти цитируемый пост)
да с чего вы взяли что всегда копии?

Если параметры функции - не ссылки, то по-другому быть не может smile

Автор: mes 25.12.2008, 17:33
Цитата(GoldFinch @  25.12.2008,  16:00 Найти цитируемый пост)
пусть не асинхронная, но в SendMessage параметры сообщения передаются окну без копирования, если в lparam указатель на переменную - никто не скопирует эту переменную 

Ну и где Вы видите проблему ? При отсылке между потоками ? Так там нельзя использовать эту функцию  smile 
При пользовании окном этого указателя, в следующем цикле ? так если окну нужны данные, оно должно сохранить их , а не указатель. 

Автор: UnrealMan 25.12.2008, 18:36
Цитата(mes @  25.12.2008,  17:33 Найти цитируемый пост)
Ну и где Вы видите проблему ? При отсылке между потоками ? Так там нельзя использовать эту функцию  

Как это нельзя? smile Её можно использовать даже для отсылки данных между процессами (см. http://msdn.microsoft.com/en-us/library/ms649011.aspx). Разумеется, все полезные данные при такой отсылке должны копироваться.

Автор: mes 25.12.2008, 18:45
Цитата(UnrealMan @  25.12.2008,  18:36 Найти цитируемый пост)
Как это нельзя? smile

ошибся.. ( Хотя  сути не меняет. )


Автор: J0ker 25.12.2008, 19:03
UnrealMan, кончай морочить детям голову  smile 

Дети, UnrealMan вам намякивает, что объект самостоятельно может управлять своим жизненным циклом - без привлечения внимания вызывающего кода - вопрос лишь в правильном интерфейсе

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)