Как работает такое приведение типов?
От: Sash_net  
Дата: 22.07.10 11:45
Оценка:
Здраствуйте,

Попадаются в коде такие конструкции:
void fnc(void)
{
    int *r;
    //...
    
    if()
        *r = (int)r1; // r1 type: char
    else 
        *r = (int)r2; // r2 type: short
    //...
    
    printf("%d", *r);
}


Обьясните пожалуста как это работает и работает ли вообще в плане выделения памяти/времени жизни/области видимости (когда выделяется память для результата преобразования, выделяется ли вообще, когда освобождается, может ли программа падать изза этого)?

Спасибо.

ПС: фикшу чужий код, расчитанный на компилируется под разные версии юникса/линукса, после портирования под новую (64-разрядную) версию с применением нового компилятора перлы типа приведения char* в int приводят к сегментейшн фолдам, хотя раньше вроде работало (но возможно дебаг-режим где есть такие преобразования никто раньше нормально не тестировал), есть и более замысловатые конструкции типа той что выше.
Re: Как работает такое приведение типов?
От: dilmah США  
Дата: 22.07.10 12:18
Оценка:
S_>Обьясните пожалуста как это работает и работает ли вообще в плане выделения памяти/времени жизни/области видимости (когда выделяется память для результата преобразования, выделяется ли вообще, когда освобождается, может ли программа падать изза этого)?

если r1 это действительно char, а r2 это действительно short, то это абсолютно корректный код. Никакая дополнительная память не выделяется.
Re: Как работает такое приведение типов?
От: andrey.desman  
Дата: 22.07.10 12:33
Оценка:
Здравствуйте, Sash_net, Вы писали:

S_>ПС: фикшу чужий код, расчитанный на компилируется под разные версии юникса/линукса, после портирования под новую (64-разрядную) версию с применением нового компилятора перлы типа приведения char* в int приводят к сегментейшн фолдам, хотя раньше вроде работало (но возможно дебаг-режим где есть такие преобразования никто раньше нормально не тестировал), есть и более замысловатые конструкции типа той что выше.


Это ж ппц! Мало того, что UB на любой платформе, так на 64 битах еще и пол адреса срезается.
Низзя так делать.
Re[2]: Как работает такое приведение типов?
От: Sash_net  
Дата: 22.07.10 13:02
Оценка:
Здравствуйте, dilmah, Вы писали:

D>если r1 это действительно char, а r2 это действительно short, то это абсолютно корректный код. Никакая дополнительная память не выделяется.


char и short занимают меньше памяти чем int. Переменная int не создавалась вообще. printf читает из памяти 4 байта по указателю r. Что именно он читает? начальные байты short/char + то что дальше?
Re[2]: Как работает такое приведение типов?
От: Sash_net  
Дата: 22.07.10 13:04
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, Sash_net, Вы писали:


AD>Это ж ппц! Мало того, что UB на любой платформе, так на 64 битах еще и пол адреса срезается.

AD>Низзя так делать.

Между версиями поменялся тип какойто переменной с short на строку char[]. Основной код пофиксили, а трейсы-логи забыли.
Re[3]: Как работает такое приведение типов?
От: dilmah США  
Дата: 22.07.10 13:38
Оценка: 2 (1)
S_>char и short занимают меньше памяти чем int.

не проблема

S> Переменная int не создавалась вообще.


а, ну я думал что она создалась там где троеточие. Конечно r должен указывать на какой-то int.

S> printf читает из памяти 4 байта по указателю r. Что именно он читает? начальные байты short/char + то что дальше?


он читает нормальный инт, полученный расширением исходного char или short. Во время присваивания *r = (int)r1; происходит "расширение", недостающие байты заполняются нулями или знаковым битом (sign extension). Тут все корректно.
Re: Как работает такое приведение типов?
От: MasterZiv СССР  
Дата: 23.07.10 06:55
Оценка:
Sash_net wrote:

> Попадаются в коде такие конструкции:

>
> void fnc(void)
> {
> int *r;
> //...
>
> if()
> *r = (int)r1; // r1 type: char

Получается значение переменной r1 типа char(это число) и это значение
преобразуется в значение типа int, затем производится присваивание этого
значения переменной типа int, адрес
которой хранится в r.

> else

> *r = (int)r2; // r2 type: short

Получается значение переменной r2 типа short int и это значение преобразуется
в значение типа int, затем производится присваивание этого значения переменной
типа int, адрес
которой хранится в r.

> Обьясните пожалуста как это работает и работает ли вообще в плане

> выделения памяти/времени жизни/области видимости (когда выделяется

Выделения памяти тут вообще нет. И работы с памятью нет.

> память для результата преобразования, выделяется ли вообще, когда

> освобождается, может ли программа падать изза этого)?

Не может.

Код абсолютно валидный. Разве что только

*r = int(r1);
или
*r = static_cast<int>(r1);

если это С++.


Очень странно, что тут вообще могло вызывать подозрение.
Posted via RSDN NNTP Server 2.1 beta
Re: Как работает такое приведение типов?
От: Vamp Россия  
Дата: 23.07.10 21:55
Оценка:
S_>приведения char* в int
А как можно это делать на 64-битной системе? Эти типы имеют разный размер.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Как работает такое приведение типов?
От: Sash_net  
Дата: 24.07.10 05:03
Оценка:
Здравствуйте, Vamp, Вы писали:

S_>>приведения char* в int

V>А как можно это делать на 64-битной системе? Эти типы имеют разный размер.

Этого делать нельзя, но я писал выше как это получилось. А что, должен ругатся компилятор на такие вещи? Не ругается, используется сс 11 насколько я понимаю, ос — солярис.

ПС: 4 дня назад тестеры открыли immediately баг, на фикс такого дается несколько часов. Все еще фикшу тотже модуль, еще несколько багов нашел, правда уже не таких тупых. Человек который его портировал в отпуске , подозреваю что он его вообще не запускал, ну или модуль у него ниразу не отрабатывал нормально . Наверно сегодня тоже на работу пойду
Re[2]: Как работает такое приведение типов?
От: alex_mah Россия www.elsy.ru
Дата: 18.08.10 09:39
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>... адрес которой хранится в r.


Вопрос в том, что хранится в этой переменной, неинициализированный мусор, NULL или все таки адрес существующей переменной.

К сожалению, ТС скрыл это дело за троеточием, а именно это и важно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.