(float) и static_cast(float): в чем разница?
От: Pavor  
Дата: 14.08.07 03:35
Оценка:
(float) и static_cast(float): в чем разница?
Собственно вот такой вопрос и есть..
Re: (float) и static_cast(float): в чем разница?
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 14.08.07 03:47
Оценка:
Здравствуйте, Pavor, Вы писали:

P>(float) и static_cast(float): в чем разница?

P>Собственно вот такой вопрос и есть..

http://rsdn.ru/?Forum/Info/FAQ.cpp.c-stylecast.aspx
... << RSDN@Home 1.2.0 alpha rev. 711>>
Re: (float) и static_cast(float): в чем разница?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 14.08.07 06:37
Оценка: 1 (1)
Здравствуйте, Pavor, Вы писали:

P>(float) и static_cast(float): в чем разница?

P>Собственно вот такой вопрос и есть..

Про static_cast сказали
Автор: Odi$$ey
Дата: 14.08.07
, от себя ещё добавлю разницу между (float) и const_cast<float> применительно к константным объектам, которую ощутил на собственной шкуре.
Однажды я писал под одну PDA платформу. На той платформе, как практически на всех ранних PDA платформах, вся память делилась на 2 части — псевдо-постоянная и псевдо-оперативная. 1-ая — типа жёсткого диска, на ней находиться исполняемый код, эта область самая большая. 2-ая — типа оперативной памяти, там находятся динамические данные, она маленькая. Псевдо, поому что реально всё лежало на одной флэшке. Как и любой современный компилятор, тот компилятор, который использовал я, старался все постоянные данные вычислить при компиляции и разместить внутри исполняемого кода, чтобы они оказались в 1-ой области памяти и не занимали место во 2-ой. На той платформе примерно вот такой код:
const long val = 10;
...
(long)val = 15;

приводил к аппаратной ошибке: Запись в область памяти, недоступную для динамического изменения. Из анализа сообщения было понятно, что идёт попытка записи в 1-ую область памяти, что недопустимо. То ли это был прикол компилятора (который не прочухивал изменение константы с применением C-style преобразования, и размещал её в коде не смотря ни на что), то ли платформы, то ли симбиоз компилятора и платформы, сказать трудно. Замена (long) на const_cast<long> решило проблему и код в такой виде:
const long val = 10;
...
const_cast<long>(val) = 15;

увидел свет...

Мораль, НИКОГДА не снимайте константность с переменных, а если это вам всё таки нужно НЕ ИСПОЛЬЗУЙТЕ для этих целей C-style — снимайте константность ТОЛЬКО с помощью const_cast.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[2]: (float) и static_cast(float): в чем разница?
От: remark Россия http://www.1024cores.net/
Дата: 14.08.07 07:03
Оценка: +4
Здравствуйте, Mr. None, Вы писали:

MN>Замена (long) на const_cast<long> решило проблему и код в такой виде:

MN>
MN>const long val = 10;
MN>...
MN>const_cast<long>(val) = 15;
MN>

MN>увидел свет...

MN>Мораль, НИКОГДА не снимайте константность с переменных, а если это вам всё таки нужно НЕ ИСПОЛЬЗУЙТЕ для этих целей C-style — снимайте константность ТОЛЬКО с помощью const_cast.


IMHO, это тоже UB, и тоже не должно работать...


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: (float) и static_cast(float): в чем разница?
От: Roman Odaisky Украина  
Дата: 14.08.07 07:30
Оценка: 1 (1)
Здравствуйте, remark, Вы писали:

MN>>Замена (long) на const_cast<long> решило проблему и код в такой виде:

MN>>
MN>>const long val = 10;
MN>>...
MN>>const_cast<long>(val) = 15;
MN>>

MN>>увидел свет...

MN>>Мораль, НИКОГДА не снимайте константность с переменных, а если это вам всё таки нужно НЕ ИСПОЛЬЗУЙТЕ для этих целей C-style — снимайте константность ТОЛЬКО с помощью const_cast.


R>IMHO, это тоже UB, и тоже не должно работать...


+1, если val размещена в памяти только для чтения, тут ничто не поможет.

Кстати, тот код даже ill-formed, надо было const_cast<long &>. А вообще const_cast можно использовать только для того, чтобы получить из константной ссылки (указателя), указывающей на неконстантный объект, неконстантную ссылку (указатель).
X x;
X const& y = x;
X& z = const_cast<X &>(y); // well-formed, well-defined

Что еще нужно помнить про const_cast: он работает не только с квалификаторои const, но и с volatile, и может незаметно сбросить последний, отчего и без того трудноуловимые многопоточные баги станут еще менее приятны.
До последнего не верил в пирамиду Лебедева.
Re[2]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 07:36
Оценка: -1
Здравствуйте, Mr. None, Вы писали:
MN>
MN>const long val = 10;
MN>...
MN>(long)val = 15;
MN>

MN>
MN>const long val = 10;
MN>...
MN>const_cast<long>(val) = 15;
MN>


и то и другое не левое. Это какойто сильно неправильный компилятор
Re[3]: (float) и static_cast(float): в чем разница?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 14.08.07 08:10
Оценка:
Здравствуйте, Programador, Вы писали:

P>Здравствуйте, Mr. None, Вы писали:

MN>>
MN>>const long val = 10;
MN>>...
MN>>(long)val = 15;
MN>>

MN>>
MN>>const long val = 10;
MN>>...
MN>>const_cast<long>(val) = 15;
MN>>


P>и то и другое не левое. Это какойто сильно неправильный компилятор


Писал по мотивам, подробностей уже всех не помню, так как было лет 5 назад. Но смысл именно такой, const_cast лечило проблему. А компилятор кстати был Code Warrior...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[3]: (float) и static_cast(float): в чем разница?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 14.08.07 08:11
Оценка:
Здравствуйте, remark, Вы писали:

R>Здравствуйте, Mr. None, Вы писали:


MN>>Замена (long) на const_cast<long> решило проблему и код в такой виде:

MN>>
MN>>const long val = 10;
MN>>...
MN>>const_cast<long>(val) = 15;
MN>>

MN>>увидел свет...

MN>>Мораль, НИКОГДА не снимайте константность с переменных, а если это вам всё таки нужно НЕ ИСПОЛЬЗУЙТЕ для этих целей C-style — снимайте константность ТОЛЬКО с помощью const_cast.


R>IMHO, это тоже UB, и тоже не должно работать...


R>


Уже ответил здесь
Автор: Mr. None
Дата: 14.08.07
.
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[4]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 08:41
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Писал по мотивам, подробностей уже всех не помню, так как было лет 5 назад. Но смысл именно такой, const_cast лечило проблему. А компилятор кстати был Code Warrior...

Дело в следующем — флэш конечно допускает запись (возможно блочную), допускаю что Code Warrior какимто образом это делает, но эта ситуация уже за пределами стандарта. А вообще для записи нужно приводить к ссылке (int&)
Re[5]: (float) и static_cast(float): в чем разница?
От: Sergey Россия  
Дата: 14.08.07 09:21
Оценка:
> MN>Писал по мотивам, подробностей уже всех не помню, так как было лет 5 назад. Но смысл именно такой, const_cast лечило проблему. А компилятор кстати был Code Warrior...
> Дело в следующем — флэш конечно допускает запись (возможно блочную), допускаю что Code Warrior какимто образом это делает, но эта ситуация уже за пределами стандарта. А вообще для записи нужно приводить к ссылке (int&)
>

По стандарту, как тут уже говорил remark, тут UB в обоих случаях. Соответственно, Code Warrior в своем праве — че хочет, то и делает.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 10:50
Оценка:
Здравствуйте, Sergey, Вы писали:

>> MN>Писал по мотивам, подробностей уже всех не помню, так как было лет 5 назад. Но смысл именно такой, const_cast лечило проблему. А компилятор кстати был Code Warrior...

>> Дело в следующем — флэш конечно допускает запись (возможно блочную), допускаю что Code Warrior какимто образом это делает, но эта ситуация уже за пределами стандарта. А вообще для записи нужно приводить к ссылке (int&)
>>

S>По стандарту, как тут уже говорил remark, тут UB в обоих случаях. Соответственно, Code Warrior в своем праве — че хочет, то и делает.

Да нетже, здесь UB по одной причине + ill-formed по другой, еще Roman Odaisky это отметил (не видел его поста когда писал)
Re: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 12:07
Оценка:
Здравствуйте, Pavor, Вы писали:

P>(float) и static_cast(float): в чем разница?

P>Собственно вот такой вопрос и есть..
порылся в стандарте,

5.2.9 Static cast [expr.static.cast]
1 The result of the expression static_cast<T>(v) is the result of converting the expression v to type T.
If T is a reference type, the result is an lvalue; otherwise, the result is an rvalue. Types shall not be defined in a static_cast. The static_cast operator shall not cast away constness (5.2.11).

попробовал разные компиляторы, результат для структуры и целого отличается. Собственно зачем писать (T) когда нужно (&T).

Но вот это меня сильно озадачило

struct St {int v;St(int);};

void f()
{ typedef int T;
  //typedef St T;

  T a=1;
  static_cast<T>(a)=__LINE__; //expression must be a modifiable lvalue
  (T)a=__LINE__; //expression must be a modifiable lvalue

  T(a)=__LINE__; // "a" has already been declared in the current scope
  {
    T(c)=__LINE__;
    T(b)=__LINE__;
    c=b;
    c=T(b);
  } 
}
Re: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 13:29
Оценка:
так что — никто не знает?

void f()
{ int a;
  int(a);//error: "a" has already been declared in the current scope
  int((int)a);// warning: expression has no effect
  int(0);// warning
  int;//warning: ignored on left of 'int' when no variable is declared
}
Re[2]: (float) и static_cast(float): в чем разница?
От: Аноним  
Дата: 14.08.07 13:44
Оценка:
Здравствуйте, Programador, Вы писали:

P>так что — никто не знает?


P>
P>void f()
P>{ int a;
P>  int(a);//error: "a" has already been declared in the current scope
P>  int((int)a);// warning: expression has no effect
P>  int(0);// warning
P>  int;//warning: ignored on left of 'int' when no variable is declared
P>}
P>


И? Нужно перевести текст ошибок/предупреждений на русский?
Re[2]: (float) и static_cast(float): в чем разница?
От: BitField Украина http://lazy-bitfield.blogspot.com
Дата: 14.08.07 14:06
Оценка: +1
Здравствуйте, Programador, Вы писали:



P>>  int a;   // обьявление переменной a..
P>>  int(a);  // еще обно обьявление переменной а
Re[3]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 14:18
Оценка:
Здравствуйте, BitField, Вы писали:

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



BF>

P>>>  int a;   // обьявление переменной a..
P>>>  int(a);  // еще обно обьявление переменной а
BF>

С чегобы это еще обно обьявление?
Это вызов конструктора и создание безымянной переменной, чем это отличается от следующей строчки?
Еслиб int a; была в внешнем контексте то так и скомпилировалосьбы.
Вот захотелось позвать конструктор, а обьект не нужен — ситуация крайне двухсмысленная
Re[3]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 14:28
Оценка:
Здравствуйте, Аноним, Вы писали:

А>И? Нужно перевести текст ошибок/предупреждений на русский?

В стандарте гдето сказано что скобки можно добавлять и убирать где попало?
Re[2]: (float) и static_cast(float): в чем разница?
От: Erop Россия  
Дата: 14.08.07 15:58
Оценка:
Здравствуйте, Programador, Вы писали:
P>  T a=1;
P>  T(a)=__LINE__; // "a" has already been declared in the current scope[/b]


А что не так? Всё что может быть декларацией -- ей и является.

T (a); -- это декларация a типа T с лишними скобками, что собственно не мешает.
T(a) = __LINE__; то же, но с инициализатором
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: (float) и static_cast(float): в чем разница?
От: Erop Россия  
Дата: 14.08.07 16:00
Оценка:
P>С чегобы это еще обно обьявление?
P>Это вызов конструктора и создание безымянной переменной, чем это отличается от следующей строчки?
P>Еслиб int a; была в внешнем контексте то так и скомпилировалосьбы.
P>Вот захотелось позвать конструктор, а обьект не нужен — ситуация крайне двухсмысленная

Есть правило -- всё, что может быть декларацией, ей и является.
Вот оно самое и есть.

Если хлчешь безымянный объект породить, сделай так, чтобы не было декларацией. Скажем так:
1, int( a );
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 14.08.07 18:05
Оценка:
Здравствуйте, Erop, Вы писали:

E>Есть правило -- всё, что может быть декларацией, ей и является.

Похоже что все компиляторы себя так ведут

Но засада класная

struct Struct
{  Struct(int,int)
    {
    }
  Struct(int)
    {
    }
  Struct()
    {
    }
};


int main(int , char **)
{   int aa;
    {  Struct(aa,aa);
       Struct(aa);
       Struct();
    }
}
Re[6]: (float) и static_cast(float): в чем разница?
От: Erop Россия  
Дата: 14.08.07 22:31
Оценка: +1
Здравствуйте, Programador, Вы писали:

E>>Есть правило -- всё, что может быть декларацией, ей и является.

P>Похоже что все компиляторы себя так ведут
Да это где-то в стандарте в "основных понятиях" записано. Просто нет сейчас, чтобы искать.

P>Но засада класная

А где "спасибо"?

Лично мне больше нравится другая версия той же засады:
struct XXX {
    XXX();
    XXX( int );
};

void foo()
{
    XXX qu( 5 ); // объявили переменную qu
    XXX ququ(); // объявили функцию ququ:)
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: (float) и static_cast(float): в чем разница?
От: Programador  
Дата: 15.08.07 05:46
Оценка:
Здравствуйте, Erop, Вы писали:

P>>Но засада класная

E>А где "спасибо"?

спасибо
Еще большое писателям стандарта

E>Если хлчешь безымянный объект породить, сделай так, чтобы не было декларацией. Скажем так:

E>
1, int( a );

кстати на (int a); ругается поэтому (ххх(аа)); обьявлением не является. Более явный метод позвать конструктор. Хотя после этого уже во всем сомневаешся
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.