VladislavS 39 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 11 минут назад, RadiatoR сказал: Почему constexpr без нее не должен работать? Потому что constexpr это не про оптимизацию! 13 минут назад, RadiatoR сказал: Подтверждаю - с O3 старый код заработал "правильно". Скорее всего и с -О1 заработает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба Constexpr это про константность результата. Он всегда один и тот же? Поменяться не может? Ни от чего не зависит? Всё! Cpnstexpr на этом заканчивается. За то как это значение получается он не отвечает. Ждём consteval. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RadiatoR 2 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 25 minutes ago, VladislavS said: Потому что constexpr это не про оптимизацию! Так я не могу понять, почему без оптимизации он вычисляется в рантайме, а не в компилтайме. 1 minute ago, VladislavS said: Constexpr это про константность результата. Он всегда один и тот же? Поменяться не может? Ни от чего не зависит? Всё! Cpnstexpr на этом заканчивается. За то как это значение получается он не отвечает. Ждём consteval. Аа, понял. Спасибо за разъяснение. Тогда ждем =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 39 минут назад, RadiatoR сказал: Пускай сейчас она отключена и он не оптимизирует. Почему constexpr без нее не должен работать? Думаю, дело в том, что по отношению к функциям constexpr является лишь рекомендацией. Как inline. Видимо, компилятор считает, что так отладка будет удобнее. Кстати, есть ключ -Og, который позволяет более-менее удобно отлаживать код, при этом не отключая полностью оптимизацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SII 0 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба constexpr у функции, насколько помню, указывает, что значение функции будет константой, если все операнды функции -- константы. Например, constexpr int max(int A, int B) -- очевидно, что если и A, и B являются константами, то максимальная из них тоже будет константой и может быть определена на этапе компиляции. Но это совершенно не требует от компилятора проводить данную оптимизацию, это лишь разрешает ему такое творить (по сути, программист с помощью constexpr обещает компилятору, что никаких побочных эффектов и неявных обращений к незнамо чему функция не выполняет). А вот использование constexpr вместо const позволяет объявить константу, под которую не выделяется память, и компилятор обязан создать константу. До появления constexpr такое только с помощью #define можно было сделать, но, понятно, это костыль. Обычный же const -- это "неизменяемая переменная", память под которую всё равно выделяется, на неё можно получить указатель и т.п., и не факт, что компилятор сможет её оптимизировать таким образом, чтобы не хранить её значение в памяти, если фактической нужды в этом нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 4 minutes ago, SII said: и компилятор обязан создать константу Как я понял из статьи, ссылку на которую я дал выше, и это не обязательно) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 1 час назад, haker_fox сказал: Как я понял из статьи, ссылку на которую я дал выше, и это не обязательно) В случае constexrp- переменной, типа static constexpr auto mySuperPuperConstexprVariable { 42 }; - обязательно. Если компилятор не сможет её вычислить во время компиляции, то он обязан выдать ошибку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RadiatoR 2 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 18 minutes ago, AHTOXA said: В случае constexrp- переменной, типа static constexpr auto mySuperPuperConstexprVariable { 42 }; - обязательно. Если компилятор не сможет её вычислить во время компиляции, то он обязан выдать ошибку. Проверил. Даже без static в случае не const вываливается с ошибкой: volatile int ia; constexpr int my = ia + 1; В общем constexpr к функциям только позволяет компилятору рассчитывать в компилтайме, а к переменным обязывает судя по всему. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 49 минут назад, RadiatoR сказал: В общем constexpr к функциям только позволяет компилятору рассчитывать в компилтайме, Не так! Обязывает компилятор проконтролировать константность возвращаемого результата. Если значение функции будет вычисляться из чего-то неконстантного, то получишь ошибку. Вычислять в компайлтайме компилятор может и без всяких conxtexpr, достаточно включить оптимизацию. Убери из примера в первом сообщении все constexpr и ничего вообще не изменится. Constexpr для функции это средство контроля. Static это вообще из другой оперы, с const и constexpr вообще никак не связано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 41 минуту назад, VladislavS сказал: Не так! Обязывает компилятор проконтролировать константность возвращаемого результата. Если значение функции будет вычисляться из чего-то неконстантного, то получишь ошибку. Ну здрасьте. Только вроде бы всё выяснили, и всё снова :-) Вот пример (можно потыкать онлайн): constexpr unsigned square(unsigned i) { return i * i; } constexpr auto ci { 0u }; int main() { unsigned t = std::time(0); std::cout << "Вызов с константой: " << square(2) << std::endl; std::cout << "Вызов с переменной: " << square(t) << std::endl; } Значение функции вычисляется из неконстантного аргумента. И никакой ошибки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Grizzly 0 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 4 минуты назад, AHTOXA сказал: Значение функции вычисляется из неконстантного аргумента. И никакой ошибки. Опередили меня. Слишком долго с телефона набирал :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RadiatoR 2 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 8 minutes ago, AHTOXA said: Значение функции вычисляется из неконстантного аргумента. И никакой ошибки. Получается, при включенной оптимизации, constexpr для функций вообще ничего не значит... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба Не совсем так. Результат вызова constexpr-функции можно присваивать constexpr-переменной. А результат вызова не-constexpr-функции - нельзя: int f1(int i) { return i * i; } constexpr int f2(int i) { return i * i; } int main() { constexpr auto i1 = f1(2); // ошибка! constexpr auto i2 = f2(2); // порядок. } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Grizzly 0 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба 1 минуту назад, AHTOXA сказал: Результат вызова constexpr-функции можно присваивать constexpr-переменной. Вот в этом случае будет 100% гарантия того, что все вычислилось во время компиляции, если не будет ошибок от компилятора. Не придется открывать листинг :) В общем случае я бы не стал смешивать constexpr и оптимизацию. Оптимизация будет зависеть от конкретного компилятора, поэтому нельзя, глядя на код, предугадать, что будет вычисляться во время компиляции, если не указать constexpr. В случае из цитаты @AHTOXA такой неоднозначности нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RadiatoR 2 2 февраля, 2020 Опубликовано 2 февраля, 2020 · Жалоба Действительно. #include <iostream> #include <cstdlib> constexpr int f2(int i) { return i * i; } int main() { volatile int x; constexpr auto i2 = f2(x); // ошибка. } Проверил этот код. Тоже вываливается с ошибкой. В итоге выходит, что constexpr к функции ничего не "должна". А к переменной предъявляет однозначный расчет в компилтайме и присвоение через constexpr функцию, либо напрямую константой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться