Re[2]: Багафича VS8?!!
От: Кодт Россия  
Дата: 09.06.07 12:06
Оценка: 1 (1) :))
Здравствуйте, Programador, Вы писали:

P>#include <math.h>
P>const int A::a=sin(0.);

В данном контексте sin() — это грех() .
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: Багафича VS8?!!
От: Smal Россия  
Дата: 08.06.07 10:29
Оценка: +3
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?



А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>


В стандарте говорится, что в этом случае будет UB. (ссылку искать лениво)
С точки зрения компилятора: ты объявил константу, компилятор положил ее в
readonly память. А теперь ты пытаешься туда лезть? Что ему делать, если память RO?
С уважением, Александр
Re[6]: Багафича VS8?!!
От: Bell Россия  
Дата: 08.06.07 12:07
Оценка: 2 (2)
Здравствуйте, shnyaps, Вы писали:

S>а можно ссыдку на стандарт?


7.1.5.1/4
Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
object during its lifetime (3.8) results in undefined behavior.


В 7.1.5.1/5 есть пример.
Любите книгу — источник знаний (с) М.Горький
Re[2]: Багафича VS8?!!
От: Programador  
Дата: 08.06.07 13:20
Оценка: :))
Здравствуйте, Аноним, Вы писали:

А>сдается мне, что static const для встроенных типов объявленных в классах — костанты времени компиляции.. выводы делаем сами

Да повсякому. Если const int A::a=0; впереди main то времени компиляции, а если позади то рунтайм. Инициализация через функцию переводит в записываемый сегмент
Re[12]: Багафича VS8?!!
От: elcste  
Дата: 13.06.07 08:33
Оценка: 52 (1)
Здравствуйте, Кодт, Вы писали:

К>Впрочем, я сейчас попробовал скомпилировать вот такой простой код

К>void trash(const double&); // пишет туда мусор
К>void crash(const double&); // читает мусор и валится

К>int main()
К>{
К>    trash(1.23);
К>    crash(1.23);
К>}

К>с разными опциями — но VC всегда копирует глобальную константу перед каждым вызовом.

К>Боится


Просто соответствует стандарту. В порядке исключения.

Когда rvalue встроенного типа привязывается к ссылке, создается временный объект и инициализируется значением rvalue. К этому временному объекту и привязывается ссылка.

8.5.3/5 — Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary.


Ничто в стандарте не запрещает модифицировать этот временный объект.
Re[8]: Багафича VS8?!!
От: Андрей Тарасевич Беларусь  
Дата: 10.06.07 16:00
Оценка: 1 (1)
Здравствуйте, Programador, Вы писали:

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


B>>

B>>7.1.5.1/4
B>>Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
B>>object during its lifetime (3.8) results in undefined behavior.


B>>В 7.1.5.1/5 есть пример.


P>И как это понимать? Получается любой!!! const_cast — UB


Нет. Получается, что сам 'const_cast' — никогда не UB. А вот собственно попытка модификации неконстантного обьъекта через полученный при помощи 'const_cast' указатель — это уже UB.
Best regards,
Андрей Тарасевич
Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 10:09
Оценка: :)
Почему всплывает exception? Это как то отражено в стандарте?


struct A {
    void f(int aa) { const_cast<int&>(a)=aa;}
    static const int a;
};
const int A::a=0;

int main() {
    A a;
    int b(0);
    a.f(b);
}
Re: Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 11:39
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?



А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>


Подтверждение не найдено значит все же багафича или пятницо ( здесь
Автор: Smal
Дата: 08.06.07
)
Re: Багафича VS8?!!
От: Programador  
Дата: 08.06.07 12:02
Оценка: -1
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?


Всплывает, но лечится легко
#include <math.h>
const int A::a=sin(0.);
Re: Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 12:46
Оценка: -1
Здравствуйте, Аноним, Вы писали:
А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>


сдается мне, что static const для встроенных типов объявленных в классах — костанты времени компиляции.. выводы делаем сами
Re: Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 10:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?



А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>

Так работает:
struct A {
void f(int aa) { const_cast<int&>(a)=aa;}
static int a;
};
int A::a=0;

int main() {
A a;
int b(0);
a.f(b);
}

странно... может, находится в read-only сегменте данных..
Re[2]: Багафича VS8?!!
От: Smal Россия  
Дата: 08.06.07 10:33
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>>Почему всплывает exception? Это как то отражено в стандарте?



А>>
А>>struct A {
А>>    void f(int aa) { const_cast<int&>(a)=aa;}
А>>    static const int a;
А>>};
А>>const int A::a=0;

А>>int main() {
А>>    A a;
А>>    int b(0);
А>>    a.f(b);
А>>}
А>>

А>Так работает:
А>struct A {
А> void f(int aa) { const_cast<int&>(a)=aa;}
А> static int a;
А>};
А>int A::a=0;

А>int main() {

А> A a;
А> int b(0);
А> a.f(b);
А>}

А>странно... может, находится в read-only сегменте данных..

А>

Ничего странного в этом нет.
С уважением, Александр
Re[3]: Багафича VS8?!!
От: shnyaps  
Дата: 08.06.07 10:38
Оценка:
Здравствуйте, Smal, Вы писали:

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


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


А>>>Почему всплывает exception? Это как то отражено в стандарте?



А>>>
А>>>struct A {
А>>>    void f(int aa) { const_cast<int&>(a)=aa;}
А>>>    static const int a;
А>>>};
А>>>const int A::a=0;

А>>>int main() {
А>>>    A a;
А>>>    int b(0);
А>>>    a.f(b);
А>>>}
А>>>

А>>Так работает:
А>>struct A {
А>> void f(int aa) { const_cast<int&>(a)=aa;}
А>> static int a;
А>>};
А>>int A::a=0;

А>>int main() {

А>> A a;
А>> int b(0);
А>> a.f(b);
А>>}

А>>странно... может, находится в read-only сегменте данных..

А>>

S>Ничего странного в этом нет.


Почему тогда?
Re[4]: Багафича VS8?!!
От: Smal Россия  
Дата: 08.06.07 10:40
Оценка:
Здравствуйте, shnyaps, Вы писали:

А>>>странно... может, находится в read-only сегменте данных..

А>>>

S>>Ничего странного в этом нет.


S>Почему тогда?


здесь
Автор: Smal
Дата: 08.06.07
С уважением, Александр
Re[5]: Багафича VS8?!!
От: shnyaps  
Дата: 08.06.07 10:49
Оценка:
Здравствуйте, Smal, Вы писали:

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


А>>>>странно... может, находится в read-only сегменте данных..

А>>>>

S>>>Ничего странного в этом нет.


S>>Почему тогда?


S>здесь
Автор: Smal
Дата: 08.06.07


а можно ссыдку на стандарт?
Re[7]: Багафича VS8?!!
От: Programador  
Дата: 08.06.07 12:31
Оценка:
Здравствуйте, Bell, Вы писали:

B>

B>7.1.5.1/4
B>Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
B>object during its lifetime (3.8) results in undefined behavior.


B>В 7.1.5.1/5 есть пример.


И как это понимать? Получается любой!!! const_cast — UB
Re[7]: Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 12:33
Оценка:
Здравствуйте, Bell, Вы писали:

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


S>>а можно ссыдку на стандарт?


B>

B>7.1.5.1/4
B>Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
B>object during its lifetime (3.8) results in undefined behavior.


B>В 7.1.5.1/5 есть пример.


Спасибо.
Получается для того, чтобы воспользоваться const_cast ты должен быть уверен в том, что он
ссылается на не константный тип, иначу UB. Я правильно понимаю??
Re: Багафича VS8?!!
От: Аноним  
Дата: 08.06.07 12:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?



А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>


Одного не пойму, зачем нужно присваивать ссылку на переменную размещенную в стеке (aa) статической (a).
Re[8]: Багафича VS8?!!
От: Bell Россия  
Дата: 08.06.07 12:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо.

А>Получается для того, чтобы воспользоваться const_cast ты должен быть уверен в том, что он
А>ссылается на не константный тип, иначу UB. Я правильно понимаю??

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

void f(const SomeType& obj)
{
   const_cast<SomeType&>(obj).mem = 0;
}

...

const SomeType c_obj;
SomeType obj;

f(obj);//Ok
f(c_obj);//UB
Любите книгу — источник знаний (с) М.Горький
Re[8]: Багафича VS8?!!
От: Bell Россия  
Дата: 08.06.07 12:51
Оценка:
Здравствуйте, Programador, Вы писали:

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


B>>

B>>7.1.5.1/4
B>>Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const
B>>object during its lifetime (3.8) results in undefined behavior.


B>>В 7.1.5.1/5 есть пример.


P>И как это понимать? Получается любой!!! const_cast — UB

Нет, не любой. К UB ведет снятие константности и модификация "настоящих" констант.
Любите книгу — источник знаний (с) М.Горький
Re[9]: Багафича VS8?!!
От: Programador  
Дата: 08.06.07 13:02
Оценка:
Здравствуйте, Bell, Вы писали:

P>>И как это понимать? Получается любой!!! const_cast — UB

B>Нет, не любой. К UB ведет снятие константности и модификация "настоящих" констант.
А "ненастоящие" это только те которые из обычных кастом получены
Re: to Programador etc.
От: Константин Л.  
Дата: 08.06.07 14:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Почему всплывает exception? Это как то отражено в стандарте?



А>
А>struct A {
А>    void f(int aa) { const_cast<int&>(a)=aa;}
А>    static const int a;
А>};
А>const int A::a=0;

А>int main() {
А>    A a;
А>    int b(0);
А>    a.f(b);
А>}
А>


Как правильно заметил Smal, это UB. И нечего разводить теорий
Re[10]: Багафича VS8?!!
От: Аноним  
Дата: 09.06.07 05:53
Оценка:
Здравствуйте, Programador, Вы писали:

P>А "ненастоящие" это только те которые из обычных кастом получены


Нет. В основной массе это переданные через константную ссылку.
Re[11]: Багафича VS8?!!
От: Кодт Россия  
Дата: 09.06.07 12:02
Оценка:
Здравствуйте, <Аноним>, Вы писали:

P>>А "ненастоящие" это только те которые из обычных кастом получены

А>Нет. В основной массе это переданные через константную ссылку.
Это — считай, тот же каст. Неявный.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[9]: Багафича VS8?!!
От: Кодт Россия  
Дата: 09.06.07 12:02
Оценка:
Здравствуйте, Bell, Вы писали:

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


А кстати, как разруливается ситуация:
struct Foo
{
    int x;
    Foo() : x(0) {}
    
    Foo& get() { return *this; }
    void bar() { ++x; }
};

void run(Foo& f) { f.bar(); }
void runc(const Foo& f) { run(const_cast<Foo&>(f)); }

int main()
{
    Foo().bar(); // можно
    run(Foo()); // нельзя
    run(Foo().get()); // можно
    runc(Foo()); // хак
}

В первом и третьем случае мы явно используем преобразование неконстантного rvalue к неконстантному же lvalue — в тех рамках, которые оговорены Стандартом.
В четвёртом — по факту, делаем то же самое. Но может быть, компилятор вправе сделать какие-то допущения: в том месте, где rvalue существует, его неконстантность не востребована, и следовательно, можно попробовать разместить его в секции констант или ещё какой трюк применить?

Например, если мы переделаем для числовых литералов,
void runci(const int& x) { const_cast<int&>(x)=0; }
void runcf(const double& x) { const_cast<double&>(x)=0.; }

int main()
{
    runci(rand()); // здесь будет по-настоящему временное значение, стреляй-не хочу
    runci(1); // здесь - как компилятору бог на душу положит
    runcf(1.); // а вот здесь - точно расстрел статической константы (особенность интеловских архитектур)
    double x = 1.; // можем внезапно получить 0., если до того не вылетим по защите памяти
}
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[10]: Багафича VS8?!!
От: elcste  
Дата: 09.06.07 14:03
Оценка:
Здравствуйте, Кодт, Вы писали:

К>int main()
К>{
К>    Foo().bar(); // можно
К>    run(Foo()); // нельзя
К>    run(Foo().get()); // можно
К>    runc(Foo()); // хак
К>}
К>

К>В первом и третьем случае мы явно используем преобразование неконстантного rvalue к неконстантному же lvalue — в тех рамках, которые оговорены Стандартом.
К>В четвёртом — по факту, делаем то же самое. Но может быть, компилятор вправе сделать какие-то допущения: в том месте, где rvalue существует, его неконстантность не востребована, и следовательно, можно попробовать разместить его в секции констант или ещё какой трюк применить?

К>Например, если мы переделаем для числовых литералов,

К>void runci(const int& x) { const_cast<int&>(x)=0; }
К>void runcf(const double& x) { const_cast<double&>(x)=0.; }

К>int main()
К>{
К>    runci(rand()); // здесь будет по-настоящему временное значение, стреляй-не хочу
К>    runci(1); // здесь - как компилятору бог на душу положит
К>    runcf(1.); // а вот здесь - точно расстрел статической константы (особенность интеловских архитектур)
К>    double x = 1.; // можем внезапно получить 0., если до того не вылетим по защите памяти
К>}

Почему? Все это совершенно легальные действия. Что с built-in, что с user-defined types.
Re[10]: Багафича VS8?!!
От: Programador  
Дата: 09.06.07 19:23
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Например, если мы переделаем для числовых литералов,

К>
К>void runci(const int& x) { const_cast<int&>(x)=0; }
К>void runcf(const double& x) { const_cast<double&>(x)=0.; }

К>int main()
К>{
К>    runci(rand()); // здесь будет по-настоящему временное значение, стреляй-не хочу
К>    runci(1); // здесь - как компилятору бог на душу положит
К>    runcf(1.); // а вот здесь - точно расстрел статической константы (особенность интеловских архитектур)
К>    double x = 1.; // можем внезапно получить 0., если до того не вылетим по защите памяти
К>}
К>

не вижу разницы между целым и плавающим. VC6 для обоих в стеке завел копии. Покрайней мере в дебаге, а в данном слугае сделать в дебаге по другому чем в релизе былобы крайней подлянкой
Re[11]: Багафича VS8?!!
От: Programador  
Дата: 09.06.07 19:25
Оценка:
Здравствуйте, elcste, Вы писали:

E>Здравствуйте, Кодт, Вы писали:


E>Почему? Все это совершенно легальные действия. Что с built-in, что с user-defined types.

А что означает легальные действие применительно к user-defined types?
Re[11]: Багафича VS8?!!
От: Кодт Россия  
Дата: 13.06.07 07:57
Оценка:
Здравствуйте, Programador, Вы писали:

P>не вижу разницы между целым и плавающим. VC6 для обоих в стеке завел копии. Покрайней мере в дебаге, а в данном слугае сделать в дебаге по другому чем в релизе былобы крайней подлянкой


Делать в дебаге и релизе по-разному — это не подлянка, а оптимизация.
Впрочем, я сейчас попробовал скомпилировать вот такой простой код
void trash(const double&); // пишет туда мусор
void crash(const double&); // читает мусор и валится

int main()
{
    trash(1.23);
    crash(1.23);
}

с разными опциями — но VC всегда копирует глобальную константу перед каждым вызовом.
Т.е.
const double xyz = 1.23;

int main()
{
    double tmp;
    
    tmp = xyz;
    trash(tmp);
    
    tmp = xyz;
    crash(tmp);
}

Боится
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[13]: Багафича VS8?!!
От: Кодт Россия  
Дата: 13.06.07 08:47
Оценка:
Здравствуйте, elcste, Вы писали:

E>Когда rvalue встроенного типа привязывается к ссылке, создается временный объект и инициализируется значением rvalue. К этому временному объекту и привязывается ссылка.

E>

8.5.3/5 — Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary.


E>Ничто в стандарте не запрещает модифицировать этот временный объект.


И как я понимаю, абсолютно без разницы — встроенный тип или нет.

Тогда уточняющий вопрос, чтобы сомнений вообще не было
const int* pint(const int& x) { return x; }

int main()
{
    assert( pint(1) != pint(1) );
}

Поскольку в обоих подвыражениях созданы временные объекты, то адреса у них должны (а не просто могут) быть разными? И компилятор не вправе сэкономить.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re[14]: Багафича VS8?!!
От: elcste  
Дата: 13.06.07 09:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>И как я понимаю, абсолютно без разницы — встроенный тип или нет.

К>Тогда уточняющий вопрос, чтобы сомнений вообще не было
К>const int* pint(const int& x) { return &x; }

К>int main()
К>{
К>    assert( pint(1) != pint(1) );
К>}

К>Поскольку в обоих подвыражениях созданы временные объекты, то адреса у них должны (а не просто могут) быть разными? И компилятор не вправе сэкономить.

Да, это хоть и временные, а разные объекты, и адреса у них должны быть различны. По-моему, единственное исключение из этого правила сделано для строковых литералов, и оно оговорено явно (2.13.4/2).
Re[12]: Багафича VS8?!!
От: Programador  
Дата: 14.06.07 16:39
Оценка:
Здравствуйте, Кодт, Вы писали:

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


P>>не вижу разницы между целым и плавающим. VC6 для обоих в стеке завел копии. Покрайней мере в дебаге, а в данном слугае сделать в дебаге по другому чем в релизе былобы крайней подлянкой


К>Делать в дебаге и релизе по-разному — это не подлянка, а оптимизация.


Нашей целью является релиз (по крайней мере в некоторых случаях). Тогда зачем нужен дебаг? Дебагинфо и повторенные куски кода и мертвый код (if(zero_expression){...} ) это должно быть, но зачем багги маскировать? Не очень както логично у МС помоему, я хочу теже баги что что в релизе. А то отлаживается всегда совсем не то что отдается заказчику

if(a)
 {  b=1; // этот код задублирова в режиме отладки
    ........
 }
else
 {  b=1; // в релизе можно вынести вперед
    ........
 }
Re[13]: Багафича VS8?!!
От: Кодт Россия  
Дата: 14.06.07 17:35
Оценка:
Здравствуйте, Programador, Вы писали:

P>>>не вижу разницы между целым и плавающим. VC6 для обоих в стеке завел копии. Покрайней мере в дебаге, а в данном слугае сделать в дебаге по другому чем в релизе былобы крайней подлянкой


К>>Делать в дебаге и релизе по-разному — это не подлянка, а оптимизация.


P>Нашей целью является релиз (по крайней мере в некоторых случаях). Тогда зачем нужен дебаг? Дебагинфо и повторенные куски кода и мертвый код (if(zero_expression){...} ) это должно быть, но зачем багги маскировать? Не очень както логично у МС помоему, я хочу теже баги что что в релизе. А то отлаживается всегда совсем не то что отдается заказчику


Не программист if(zero_expression), а компилятор — может и должен делать разный код.
Да, в некоторых случаях это приводит к неприятностям.

1) Главный источник неприятностей — это неопределённое и неспецифицированное поведение. Например, закладываться на порядок вызова частей выражения.
2) Далее, разница в дебажных и релизных версиях библиотек. Например, закладываться на якобы известные размеры типов (в дебажной версии STL итератор вектора может быть классом, а в релизной — указателем, и т.п.)
3) Плавающая арифметика. В зависимости от опций компилятора, а уж тем более от порядка вычислений, результат может варьироваться. А превратить вычислительную погрешность в катастрофу — дело нехитрое.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.