Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 13:31
Оценка:
При преобразовании типа должен ли создаться временный объект?
void f ( char & c ) { c = 0xAA; }

int main()
{
    int i = 0;

    cout << "i = " << i << endl;

    f( (char)i );

    cout << "i = " << i << endl;

    return 0;
}
Re: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 15:24
Оценка:
Здравствуйте, _alecs, Вы писали:

_>При преобразовании типа должен ли создаться временный объект?

_>
_>void f ( char & c ) { c = 0xAA; }

_>int main()
_>{
_>    int i = 0;

_>    cout << "i = " << i << endl;

_>    f( (char)i );

_>    cout << "i = " << i << endl;

_>    return 0;
_>}
_>


Это вообще компилироваться не должно — временный
объект передается по неконстантной ссылке. Скорей всего у вас студия =)
Надо так
    f( (char &)i );

А ещё лучше так.
    f( reinterpret_cast<char &>(i) );


Временный объект в этом случае создаваться не будет.
Но это все Undefined Behaviour!!! Так делать нельзя. (поправьте если я неправ).
С уважением, Александр
Re[2]: Преобразование типов (создаётся временный объект?).
От: Аноним  
Дата: 28.08.08 16:36
Оценка:
да я его "от руки" написал, не компилил.
вопрос был теоретический, создаётся ли временный объект:
(char)i; // i это int i;
Re[3]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 16:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>да я его "от руки" написал, не компилил.

А>вопрос был теоретический, создаётся ли временный объект:
А>
А>(char)i; // i это int i;
А>

В таком
void f( char c ) {}
//...

int i;
f ((char)i);


Да, временный объект будет создан.
С уважением, Александр
Re[4]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 16:53
Оценка:
Да нет, не в таком.

Это понятно, что при передачи по значению объект создатся. Меня интересует в таком:
int i(0);
(char)i = 0xFF;

какой байт закосячится? это хорошо если это расположения байт — x86. а если сначало хранятся старшии байты...?
Re[4]: Преобразование типов (создаётся временный объект?).
От: c-smile Канада http://terrainformatica.com
Дата: 28.08.08 16:53
Оценка:
Здравствуйте, Smal, Вы писали:

S>Здравствуйте, Аноним, Вы писали:


А>>да я его "от руки" написал, не компилил.

А>>вопрос был теоретический, создаётся ли временный объект:
А>>
А>>(char)i; // i это int i;
А>>

S>В таком
S>
S>void f( char c ) {}
S>//...

S>int i;
S>f ((char)i);
S>


S>Да, временный объект будет создан.


Что такое "временный объект" в данном контексте?
Re[5]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 16:58
Оценка:
Здравствуйте, _alecs, Вы писали:

_>Да нет, не в таком.


_>Это понятно, что при передачи по значению объект создатся. Меня интересует в таком:

_>
_>int i(0);
_>(char)i = 0xFF;
_>

_>какой байт закосячится? это хорошо если это расположения байт — x86. а если сначало хранятся старшии байты...?

Да никакой не закосячится, т.к. (char)i — не lvalue.
Если так (char &)i = 0xFF; => Undefined behaviour.
С уважением, Александр
Re[5]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 16:59
Оценка:
Здравствуйте, c-smile, Вы писали:

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


S>>Здравствуйте, Аноним, Вы писали:


А>>>да я его "от руки" написал, не компилил.

А>>>вопрос был теоретический, создаётся ли временный объект:
А>>>
А>>>(char)i; // i это int i;
А>>>

S>>В таком
S>>
S>>void f( char c ) {}
S>>//...

S>>int i;
S>>f ((char)i);
S>>


S>>Да, временный объект будет создан.


CS>Что такое "временный объект" в данном контексте?

Прошу прощения. Имелся ввиду случай с void f( char const & c ) {}
Тут действительно непонятно.
С уважением, Александр
Re[5]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 17:01
Оценка:
short i(0x7FFF);
char c = (char)i; // ?? с

что будет в 'c'? Это хорошо если расположение байт перевёрнутое, и при приобразовании в меньшую сторону мы получим крайнее значение 0xFF, а если байтики хранятся сначало старшии, то получим 0x7F? ...в зависимости от платформы?
Re[6]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 17:11
Оценка:
Здравствуйте, _alecs, Вы писали:

_>
_>short i(0x7FFF);
_>char c = (char)i; // ?? с
_>

_>что будет в 'c'? Это хорошо если расположение байт перевёрнутое, и при приобразовании в меньшую сторону мы получим крайнее значение 0xFF, а если байтики хранятся сначало старшии, то получим 0x7F? ...в зависимости от платформы?

4.7.3
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and
bit-field width); otherwise, the value is implementation-defined.

С уважением, Александр
Re[6]: Преобразование типов (создаётся временный объект?).
От: Кодт Россия  
Дата: 28.08.08 17:15
Оценка:
Здравствуйте, _alecs, Вы писали:

_>
_>short i(0x7FFF);
_>char c = (char)i; // ?? с
_>

_>что будет в 'c'? Это хорошо если расположение байт перевёрнутое, и при приобразовании в меньшую сторону мы получим крайнее значение 0xFF, а если байтики хранятся сначало старшии, то получим 0x7F? ...в зависимости от платформы?

Будьте внимательны — когда делается static_cast значения, а когда reinterpret_cast ссылки.

(char) — это static_cast. Значение типа short приводится к значению типа char и затем копируется в переменную c.
int и char — числовые типы, преобразование там арифметическое. Вообще говоря, здесь происходит целочисленное переполнение (поскольку 0x7FFF вылезло за границы CHAR_MIN..CHAR_MAX), но эта операция условно-безболезненна. Берётся остаток по модулю, сиречь младший байт.

(char&) — это реинтерпрет. Ссылка на объект типа short приводится к ссылке на объект типа char. Естественно, при этом мы уже забываем о содержимом, и работаем с байтовыми представлениями. Получаем первый байт, а является ли он младшим или старшим — зависит от архитектуры.
Перекуём баги на фичи!
Re[6]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 17:22
Оценка:
Здравствуйте, Smal, Вы писали:

S>Прошу прощения. Имелся ввиду случай с void f( char const & c ) {}

S>Тут действительно непонятно.

Здесь действительно есть неопределённость...? создаст временный объект или воспримит передаваемый объект как char...?
Re[7]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 17:28
Оценка:
Здравствуйте, _alecs, Вы писали:

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


S>>Прошу прощения. Имелся ввиду случай с void f( char const & c ) {}

S>>Тут действительно непонятно.

_>Здесь действительно есть неопределённость...? создаст временный объект или воспримит передаваемый объект как char...?

Неопределённость с понятием временный объект.

void f( char const & c ) {} => создаст временный объект
void f( char c ) {} => не создаст, а просто приведет int к char и скопирует в переменную c
С уважением, Александр
Re[8]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 17:52
Оценка:
Здравствуйте, Smal, Вы писали:

S>void f( char const & c ) {} => создаст временный объект

S>void f( char c ) {} => не создаст, а просто приведет int к char и скопирует в переменную c

А по подробней насчёт этой операции? Не является ли это созданием временного объекта?

Кстати, благодарю всех за ответы!
Re[8]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 28.08.08 18:11
Оценка:
Здравствуйте, Smal, Вы писали:

S>void f( char const & c ) {} => создаст временный объект

S>void f( char c ) {} => не создаст, а просто приведет int к char и скопирует в переменную c

Следуя логиге этих двух примеров можно сказать следующее:

В случае отличии типа передоваемого значения от требуемого операция
(char)i; // i это int i;

приведет int к char -> т.е. создаст временный объект, и передаст его по ссылки
void f( char const & c ) {}
Re[9]: Преобразование типов (создаётся временный объект?).
От: Smal Россия  
Дата: 28.08.08 18:21
Оценка:
Здравствуйте, _alecs, Вы писали:

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


S>>void f( char const & c ) {} => создаст временный объект

S>>void f( char c ) {} => не создаст, а просто приведет int к char и скопирует в переменную c

_>Следуя логиге этих двух примеров можно сказать следующее:

....
_>приведет int к char -> т.е. создаст временный объект, и передаст его по ссылки
не т.е.

приведет int к char, создаст временный объект типа char со значением (char)i,
и передаст ссылку на него в функцию void f( char const & c ) {}

Если же void f( char c ) {}, то
приведет int к char и присвоит это значение переменной c
при вызове функции f
С уважением, Александр
Re: Преобразование типов (создаётся временный объект?).
От: Alexander G Украина  
Дата: 28.08.08 21:02
Оценка:
Здравствуйте, _alecs, Вы писали:

_>При преобразовании типа должен ли создаться временный объект?


int main()
{
  int i = 42;
  (void) i; // создали временый объект типа... void ??!!?
  return 0;
}
Русский военный корабль идёт ко дну!
Re[2]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 29.08.08 22:05
Оценка:
Здравствуйте, Alexander G, Вы писали:

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

int main()
{
  int i = 42;
  void(i); // типа да.
  return 0;
}
Re[10]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 29.08.08 23:00
Оценка:
Здравствуйте, Smal, Вы писали:

S>не т.е.


S>приведет int к char, создаст временный объект типа char со значением (char)i,

S>...

Интересно, как это он приведёт допустим char к float без создания временного объекта??
Можно немного поподробней об операции приведения — приведет char к float?
Re[3]: Преобразование типов (создаётся временный объект?).
От: Юрий Жмеренецкий ICQ 380412032
Дата: 30.08.08 11:44
Оценка:
Здравствуйте, _alecs, Вы писали:

_>
_>int main()
_>{
_>  int i = 42;
_>  void(i); // типа да.
_>  return 0;
_>}
_>


5.2.9/4:

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.

Re[4]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 30.08.08 19:39
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>5.2.9/4:

Any expression can be explicitly converted to type “cv void.” The expression value is discarded.


А по руски...!
(float)char; // создали объект float.
Re[5]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 30.08.08 19:41
Оценка:
А по руски...!
char c(0);
(float)c; //  создали объект float.
Re[11]: Преобразование типов (создаётся временный объект?).
От: Юрий Жмеренецкий ICQ 380412032
Дата: 31.08.08 12:39
Оценка:
Здравствуйте, _alecs, Вы писали:

_>Интересно, как это он

Кто?

_>приведёт допустим char к float без создания временного объекта??

Все преобразования, сводимые к static_cast производятся так:

An expression e can be explicitly converted to a type T using a static_cast of the form static_cast<T>(e) if the declaration “T t(e);” is wellformed, for some invented temporary variable t (8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion.


Т.е. был ли на самом деле создан временный объект или нет — неизвестно, но результат получается такой же, как если бы он был.

Не гарантируется что одинаковые значения объектов float и char имеют одинаковые представления(representation) на уровне битов. Т.е. чтобы рассматривать значение как имеющее тип float, сначала нужно его корректно сформировать(в виде временного объекта).
Re[12]: Преобразование типов (создаётся временный объект?).
От: _alecs Россия  
Дата: 01.09.08 19:59
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

В общем, вот код:
#include "stdafx.h"
#include <iostream>

using namespace std;

class CBase
{
public:

    int i;

    CBase( int _i = 0 ) : i(_i)
    {
        cout << "Create CBase. i = " << i << endl;
    };

    ~CBase()
    {
        cout << "Destroy CBase. i = " << i  << endl;
    };
};

class CChild : public CBase
{
public:
    CChild( int _i ) : CBase(_i)
    {
        cout << "Create CChild. i = " << i  << endl;
    };

    ~CChild()
    {
        cout << "Destroy CChild. i = " << i  << endl;
    };
};

int _tmain(int argc, _TCHAR* argv[])
{
    CBase Base(1);
    CChild Child(2);

    Base = (CBase)Child;
    return 0;
}


Вот результат:

Create CBase. i = 1
Create CBase. i = 2
Create CChild. i = 2
Destroy CBase. i = 2
Destroy CChild. i = 2
Destroy CBase. i = 2
Destroy CBase. i = 2


А вот модификация, со странным результатом:

#include "stdafx.h"
#include <iostream>

using namespace std;

class CBase
{
public:

    int i;

    CBase( int _i = 0 ) : i(_i)
    {
        cout << "Create CBase. i = " << i << endl;
    };

    ~CBase()
    {
        cout << "Destroy CBase. i = " << i  << endl;
    };
};

class CChild : public CBase
{
public:
    CChild( int _i ) : CBase(_i)
    {
        cout << "Create CChild. i = " << i  << endl;
    };

    ~CChild()
    {
        cout << "Destroy CChild. i = " << i  << endl;
    };
};

int _tmain(int argc, _TCHAR* argv[])
{
    CChild Child(2);

    (CBase)Child;
    return 0;
}


Вот этот результат:

Create CBase. i = 2
Create CChild. i = 2
Destroy CBase. i = 2
Destroy CChild. i = 2
Destroy CBase. i = 2
Re[13]: Преобразование типов (создаётся временный объект?).
От: Юрий Жмеренецкий ICQ 380412032
Дата: 01.09.08 21:32
Оценка:
Здравствуйте, _alecs, Вы писали:

_>Здравствуйте, Юрий Жмеренецкий, Вы писали:


_>В общем, вот код:

...
_>А вот модификация, со странным результатом:

_>
//...
_>int _tmain(int argc, _TCHAR* argv[])
_>{
_>    CChild Child(2);

_>    (CBase)Child;
_>    return 0;
_>}
_>


_>Вот этот результат:


_>Create CBase. i = 2

_>Create CChild. i = 2
_>Destroy CBase. i = 2
_>Destroy CChild. i = 2
_>Destroy CBase. i = 2


Вопрос-то в чем ?

Все правильно. В строке '(CBase)Child;' создается временный объект с помощью конструктора копирования 'CBase::CBase(const CBase&)', который определен компилятором. В конце полного выражения этот временный объект умирает.

Если добавить copy ctor и переписать так:
CChild Child(2);
cout << "---" << endl;
(CBase)Child;
cout << "---" << endl;

То вывод будет таким:

Create CBase. i = 2
Create CChild. i = 2
---
CBase(const CBase&)
Destroy CBase. i = 2
---
Destroy CChild. i = 2
Destroy CBase. i = 2
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.