Здравствуйте, Кодт, Вы писали:
К>Тогда как другие примеры UnsB могут быть нестабильными.
Тогда как другие примеры UnsB могут быть нестабильными.
int inc(int& x) { return ++x; }
int sub(int x, int y) { return x-y; }
int x1 = 1;
int d1 = sub(inc(x1), inc(x1)); // 1-2 или 2-1 - как компилятор оптимизируетint x2 = 1;
int d2 = sub(inc(x2), inc(x2)); // 1-2 или 2-1 - независимо от того, что было выше
я немного подфиксил код, чтобы скомпилировался
откуда мысли по поводу способа вычисления d2 ?
как на практике воспроизвести?
я так понял, что может получиться d1 != d2.
Здравствуйте, uzhas, Вы писали:
U>Ведь главное — сохранять инварианты: U>&a < &b = !(&b <= &a) U>&a < &b && &b < &c => &a < &b U>и тд U>а это в стандарте не зафиксировано =\
20.3.3/8 For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Судя по тому, что object_locator::type — указатель, вроде как адрес одного объекта может быть записан в более чем одну структуру, иначе почему не включить непосредственно объект? С другой стороны есть ответ на последний вопрос — потому что размер type_info физически может быть любой (т.к. содержит имя типа).
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
20.3.3/8 For templates greater, less, greater_equal, and less_equal, the specializations for any pointer type yield a total order, even if the built-in operators <, >, <=, >= do not.
то есть стандарт всё же не против бардака в реализации этих операторах
я в шоке
Впрочем, внутри самой RTL используются следующее сравнение полей type:
bool operator==(const std::type_info* l, const std::type_info* r)
{
return l == r
|| *l == *r; // сами объекты type_info в MSVC сравниваются strcmp по имени.
}
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, uzhas, Вы писали:
U>то есть стандарт всё же не против бардака в реализации этих операторах U>я в шоке
Стандарт при этом показывает, как можно делать правильно, сохраняя совместимость с С и не болея его наследием.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, placement_new, Вы писали:
_>Здравствуйте, March_rabbit, Вы писали:
M_>>ИМХО, лучше сравнивать через strcmp и все. Надежно.
_>Так тоже лучше не делать =) Формат имени не опеределен.
ну, не помню точно, но для одного типа вроде как гарантируется уникальность имени а для сравнения на равенство двух объектов type_info этого достаточно (извиняюсь, что сразу не уточнил, что речь шла о сравнении объектов type_info).
Здравствуйте, March_rabbit, Вы писали:
M_>ну, не помню точно, но для одного типа вроде как гарантируется уникальность имени а для сравнения на равенство двух объектов type_info этого достаточно (извиняюсь, что сразу не уточнил, что речь шла о сравнении объектов type_info).
вы будете удивлены, но type_info::name, всегда для всех типов возвращающий пустую строку, не противоречит стандарту
placement_new:
_>В книге Майерса (35 новых способов улучшить ваш срр) в примечании написано, что для каждого типа объект type_info единственен, что дает нам право юзать его адрес.
Найти такое примечание у меня с ходу не получилось. Где именно Мейерс это написал?
Здравствуйте, uzhas, Вы писали:
U>я немного подфиксил код, чтобы скомпилировался
Ага, думал одно, написал другое.
U>откуда мысли по поводу способа вычисления d2 ? U>как на практике воспроизвести? U>я так понял, что может получиться d1 != d2.
Надо как-то добиться от компилятора агрессивной оптимизации.
Попробовать (в разных единицах компиляции, естественно) сочетания, когда определения функций и переменных доступны/недоступны.
Чтобы в одном случае он попробовал проинлайнить, а в другом вынужден следовать конвенции cdecl.
Мне это с разбегу не удалось. Зато удалось другое:
#include <iostream>
int inc(int& x) { return ++x; }
int sub1(int a, int b) { return a-b; }
int sub2(int const& a, int b) { return a-b; } // эквивалентно, думаете вы!int main()
{
int x1 = 1;
std::cout << sub1(inc(x1),inc(x1)); // 1, т.е. b;aint x2 = 1;
std::cout << sub2(inc(x2),inc(x2)); // -1, т.е. a;b
}