elijah@confident.ru [~] $ cat test.cpp
#include <iostream>
bool doIt = true;
int main(void)
{
doIt && std::cout << "Catch me if you can!" << std::endl;
return (0);
}
elijah@confident.ru [~] $ g++ -O3 test.cpp
elijah@confident.ru [~] $ ./a.out
Catch me if you can!
Даже с -O3 G++ не выкидывает формально порожний код. 🙄
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>bool doIt = true; SDB> doIt && std::cout << "Catch me if you can!" << std::endl;
SDB>Даже с -O3 G++ не выкидывает формально порожний код. 🙄
Вы видимо еще не отошли от праздников
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>Здравствуйте, kov_serg, Вы писали:
_>>Вы видимо еще не отошли от праздников
SDB>А конкретнее? Я понимаю, что необходимо вычислить обе части &&, но результат-то потом никак не используется и даже не сохраняется.
SDB>P.S. SDB>От праздников я еще 4 числа отошел, печенка не резиновая.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>А конкретнее? Я понимаю, что необходимо вычислить обе части &&, но результат-то потом никак не используется.
в выражении
std::cout << "Hello" << std::endl;
return 0;
результат первой строки тоже не используется. значит ли это что программа не должна ничего выводить?
Здравствуйте, Pzz, Вы писали:
Pzz>Мне одному кажется, что чтобы не было нужды вычислять вторую половину булевского выражения, надо или в doIt положить false, или заменить && на || ?
Мой пойнт был в том, что формально там написано булево выражение, результат которого не только не используется, но даже нигде не сохраняется. И я был практически уверен, что оптимизатор такое должен выкинуть, вне зависимости от того, что именно является операндами &&.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB> И я был практически уверен, что оптимизатор такое должен выкинуть, вне зависимости от того, что именно является операндами &&.
На каком основании он должен выкинуть побочные эффекты?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Здравствуйте, Pzz, Вы писали:
SDB>>Даже с -O3 G++ не выкидывает формально порожний код. 🙄
Pzz>Мне одному кажется, что чтобы не было нужды вычислять вторую половину булевского выражения, надо или в doIt положить false, или заменить && на || ?
Если operator&& переопределён, то будет вычисляться полностью
Здравствуйте, Alexander G, Вы писали:
AG>Потому что глобальная переменная, потенциально виндая в других единицах трансляции. AG>Глобальный конструктор другой единицы может переписать в false.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>А вот это уже по делу, дякую!
Перечитал ветку, на всякий случай ещё уточню.
В случае статического связывания, анонимного пространства имён или локальной переменной, компилятор выкинет само обращение к doIt.
Но результат программы будет тот же: https://godbolt.org/z/cx5P5q7bM
С точки зрения as-if правила, вывод в консоль является побочным эффектом, который выкинуть нельзя.
Русский военный корабль идёт ко дну!
Re[2]: А потому что эта глобальная переменная видна другим TU
Здравствуйте, ArtDenis, Вы писали:
AD>Ну речь-то тут идёт про вывод "Catch me if you can!" на консоль.
Ну если так то да.
Из-за упоминания -O3 я изначально воспринял вопрос как "что препятствует оптимизации, устраняющей лишнюю переменную (с сохранением ожидаемого поведения)?"
Здравствуйте, Marty, Вы писали:
Pzz>>Мне одному кажется, что чтобы не было нужды вычислять вторую половину булевского выражения, надо или в doIt положить false, или заменить && на || ?
M>Если operator&& переопределён, то будет вычисляться полностью
Это я знаю (поубивал бы за это!). Но там явно не тот случай.
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>Мой пойнт был в том, что формально там написано булево выражение, результат которого не только не используется, но даже нигде не сохраняется. И я был практически уверен, что оптимизатор такое должен выкинуть, вне зависимости от того, что именно является операндами &&.
Любой оператор присваивания в C — это выражение, значение которого не используется. Любой вызов функции без присваивания — это выражение, значение которого не успользуется. Из этого не следует, что они не вычисляются.
Но вот конкретно про встроенные (не переопределенные) булевские операторы есть гарантия, что они вычисляются слева направо, и неиспользуемая правая часть не вычисляется.
Здравствуйте, SchweinDeBurg, Вы писали:
TB>>На каком основании он должен выкинуть побочные эффекты?
SDB>Ну, я бы на его месте выкинул. Ладно, закроем тему, надо будет Стандарт покурить про этот момент поподробнее.
Вроде бы SchweinDeBurg любитель MFC, если не ошибаюсь, и вполне мог тайно увидеть такое, которое не имеет отношение к теме, но как раз было бы выкинуто в т.н. Release сборке:
SDB>bool doIt = true; SDB> doIt && std::cout << "Catch me if you can!" << std::endl;
'Суета это все' — хреновый критерий для оптимизатора. По такому критерию 99.99% софта компилятор мог бы компилировать в ret, а оставшийся 0.01% процент — это сам компилятор и то что ему требуется.
Есть стандарт, и в нем конкретно описано в каких случаях компилятор выкидывает код из булевых выражений. Это называется short-circuit evaluation и тут оно никак не могло выкинуть правое выражение по причинам на которые тут уже указали.
Как много веселых ребят, и все делают велосипед...
Re[4]: А потому что эта глобальная переменная видна другим TU
AD>>Бред же. Не выкидывает. И не должен. Точно народ перепраздновал. AG>Выкидывает, вот дифф: https://godbolt.org/z/Gfj6zs5Kf
То есть топикстартеру не понравилось наличие cmp в ассемблерном выхлопе компилятора, но рассказать об этом всем в пылу возмущения он забыл, а ты каким-то образом догадался? Какой провайдер в астралнет?
Как много веселых ребят, и все делают велосипед...
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>Здравствуйте, kov_serg, Вы писали: _>>Вы видимо еще не отошли от праздников SDB>А конкретнее? Я понимаю, что необходимо вычислить обе части &&, но результат-то потом никак не используется.
Дело не в результате, а в побочном эффекте. pure-функция была бы выкинута.
Re[5]: А потому что эта глобальная переменная видна другим TU
Здравствуйте, ononim, Вы писали:
O>То есть топикстартеру не понравилось наличие cmp в ассемблерном выхлопе компилятора, но рассказать об этом всем в пылу возмущения он забыл, а ты каким-то образом догадался? Какой провайдер в астралнет?
Здравствуйте, Pzz, Вы писали:
SDB>>Мой пойнт был в том, что формально там написано булево выражение, результат которого не только не используется, но даже нигде не сохраняется.
Формально сохраняется: "распечатывается на бумаге". Откуда программе знать, что консоль не механическая?
И вообще: ./a.out > r.txt
Здравствуйте, SchweinDeBurg, Вы писали:
TB>>На каком основании он должен выкинуть побочные эффекты?
SDB>Ну, я бы на его месте выкинул. Ладно, закроем тему, надо будет Стандарт покурить про этот момент поподробнее.