Сообщение Re: Про идентичность const от 27.01.2025 11:28
Изменено 27.01.2025 11:44 Кодт
Re: Про идентичность const
Здравствуйте, Shmj, Вы писали:
S>Имеем constexpr в конструкторе и const при создании — но выделяются разные участки памяти. Зачем? Сложно проверить и для всех таких constexpr/constexpr не выделять память по 100 раз?
S>Вроде бы мелочь, а открываются колоссальные возможности по оптимизации
Пока во время исполнения нет понятия "абсолютно константные данные", и как следствие, — неразличимые между собой копии, — колоссальные возможности по оптимизации не открываются.
(Во время компиляции они есть, но тоже с оговорками. И вот этот дуализм constexpr, конечно, вносит сумятицу).
А давай не будем далеко ходить.
Вот смотри. Пусть у тебя воистину константа
Да и сам по себе constexpr-конструктор не даёт полной гарантии на неизменность.
constexpr-ом мы просто обещаем, что эти функции можно вызывать во время компиляции тоже.
Внезапно, переприсваивать во время компиляции тоже можно.
Но и во время компиляции важнейшее свойство объектов — уникальность адресов — никуда не девается.
[/c]
constexpr Var foo1(int a, int b) {
Var* p = new Var(a, 0); // p->x = a
Var* q = new Var(b, 0); // q->x = b
p->x += q->x; // p->x = a+b q не трогаем, это отдельный объект
q->x += p->x; // q->x = a+b+b
Var v = *q;
delete p; delete q;
return v;
}
[/c]
S>Имеем constexpr в конструкторе и const при создании — но выделяются разные участки памяти. Зачем? Сложно проверить и для всех таких constexpr/constexpr не выделять память по 100 раз?
S>Вроде бы мелочь, а открываются колоссальные возможности по оптимизации
Пока во время исполнения нет понятия "абсолютно константные данные", и как следствие, — неразличимые между собой копии, — колоссальные возможности по оптимизации не открываются.
(Во время компиляции они есть, но тоже с оговорками. И вот этот дуализм constexpr, конечно, вносит сумятицу).
А давай не будем далеко ходить.
Вот смотри. Пусть у тебя воистину константа
class Konst {};
const Konst* k1 = new const Konst();
const Konst* k2 = new const Konst();
assert(*k1 == *k2); // эквивалентность значений - это мы и так уже ожидаем
assert(k1 == k2); // идентичность объектов - то, что хочешь внедрить ты
// а теперь страшное!
delete k1;
delete k2; // ведь мы сделали два new, - значит, и два delete должны
Да и сам по себе constexpr-конструктор не даёт полной гарантии на неизменность.
struct Var {
int x;
constexpr Var(int a, int b) : x(a+b) {}
};
Var v(1, 2);
v.x += 4;
constexpr-ом мы просто обещаем, что эти функции можно вызывать во время компиляции тоже.
Внезапно, переприсваивать во время компиляции тоже можно.
constexpr Var foo(int a, int b, int c) {
Var v(a, b);
v.x += c;
return v;
}
int bar[foo(1, 2, 4).x]; // тут хочешь не хочешь, а константа времени компиляции
template<Var v> struct Buz {};
Buz<foo(1, 2, 4)> buz; // Buz<Var{.x=7}> // константа времени компиляции
Но и во время компиляции важнейшее свойство объектов — уникальность адресов — никуда не девается.
[/c]
constexpr Var foo1(int a, int b) {
Var* p = new Var(a, 0); // p->x = a
Var* q = new Var(b, 0); // q->x = b
p->x += q->x; // p->x = a+b q не трогаем, это отдельный объект
q->x += p->x; // q->x = a+b+b
Var v = *q;
delete p; delete q;
return v;
}
[/c]
Re: Про идентичность const
Здравствуйте, Shmj, Вы писали:
S>Имеем constexpr в конструкторе и const при создании — но выделяются разные участки памяти. Зачем? Сложно проверить и для всех таких constexpr/constexpr не выделять память по 100 раз?
S>Вроде бы мелочь, а открываются колоссальные возможности по оптимизации
Пока во время исполнения нет понятия "абсолютно константные данные", и как следствие, — неразличимые между собой копии, — колоссальные возможности по оптимизации не открываются.
(Во время компиляции они есть, но тоже с оговорками. И вот этот дуализм constexpr, конечно, вносит сумятицу).
А давай не будем далеко ходить.
Вот смотри. Пусть у тебя воистину константа
Да и сам по себе constexpr-конструктор не даёт полной гарантии на неизменность.
constexpr-ом мы просто обещаем, что эти функции можно вызывать во время компиляции тоже.
Внезапно, переприсваивать во время компиляции тоже можно.
Но и во время компиляции важнейшее свойство объектов — уникальность адресов — никуда не девается.
S>Имеем constexpr в конструкторе и const при создании — но выделяются разные участки памяти. Зачем? Сложно проверить и для всех таких constexpr/constexpr не выделять память по 100 раз?
S>Вроде бы мелочь, а открываются колоссальные возможности по оптимизации
Пока во время исполнения нет понятия "абсолютно константные данные", и как следствие, — неразличимые между собой копии, — колоссальные возможности по оптимизации не открываются.
(Во время компиляции они есть, но тоже с оговорками. И вот этот дуализм constexpr, конечно, вносит сумятицу).
А давай не будем далеко ходить.
Вот смотри. Пусть у тебя воистину константа
class Konst {};
const Konst* k1 = new const Konst();
const Konst* k2 = new const Konst();
assert(*k1 == *k2); // эквивалентность значений - это мы и так уже ожидаем
assert(k1 == k2); // идентичность объектов - то, что хочешь внедрить ты
// а теперь страшное!
delete k1;
delete k2; // ведь мы сделали два new, - значит, и два delete должны
Да и сам по себе constexpr-конструктор не даёт полной гарантии на неизменность.
struct Var {
int x;
constexpr Var(int a, int b) : x(a+b) {}
};
Var v(1, 2);
v.x += 4;
constexpr-ом мы просто обещаем, что эти функции можно вызывать во время компиляции тоже.
Внезапно, переприсваивать во время компиляции тоже можно.
constexpr Var foo(int a, int b, int c) {
Var v(a, b);
v.x += c;
return v;
}
int bar[foo(1, 2, 4).x]; // тут хочешь не хочешь, а константа времени компиляции
template<Var v> struct Buz {};
Buz<foo(1, 2, 4)> buz; // Buz<Var{.x=7}> // константа времени компиляции
Но и во время компиляции важнейшее свойство объектов — уникальность адресов — никуда не девается.
constexpr Var foo1(int a, int b) {
Var* p = new Var(a, 0); // p->x = a
Var* q = new Var(b, 0); // q->x = b
p->x += q->x; // p->x = a+b q не трогаем, это отдельный объект
q->x += p->x; // q->x = a+b+b
Var v = *q;
delete p; delete q;
return v;
}