OberonCore
https://forum.oberoncore.ru/

C++, очередной сюрприз
https://forum.oberoncore.ru/viewtopic.php?f=27&t=2222
Страница 1 из 2

Автор:  kemiisto [ Вторник, 05 Январь, 2010 22:51 ]
Заголовок сообщения:  C++, очередной сюрприз

Оказывается С++ поддерживает двойные неравенства в роли условных выражений. :lol: Сегодня увидел. Скомпилируйте
Код:
#include <iostream>

int main (int argc, char* const argv[])
{
   int value = 1;
   
   if (0 <= value <= 5)
    std::cout << "value in [0, 5] \n";
   if (6 <= value <= 13)
    std::cout << "value in [6, 13] \n";
   if (13 <= value <= 26)
    std::cout << "value in [13, 26] \n";
   if (26 <= value <= 34)
    std::cout << "value in [26, 34] \n";
  return 0;
}

И насладитесь ответом. :twisted:

Автор:  igor [ Вторник, 05 Январь, 2010 23:16 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
Оказывается С++ поддерживает двойные неравенства в роли условных выражений. :lol:
Не вижу в таких неравенствах ничего смешного, и уж тем более ничего плохого. По сути это сокращённая запись конъюнкции двух условий:
Код:
 (0 <= value) & (value <= 5)
Это не только экономит место, но и делает текст программы более наглядным, так как математическую нотацию условных выражений все мы "всосали" ещё в школе :) .

Кстати, пример удачного сокращения можно найти и в Обероне. Сравните:
Код:
 ARRAY N1, N2 OF CHAR;
ARRAY N1 OF ARRAY N2 OF CHAR;

Автор:  kemiisto [ Вторник, 05 Январь, 2010 23:18 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor, да Вы скомпилируйте и запустите. Будете удивлены. :wink:

Цитата:
По сути это сокращённая запись конъюнкции двух условий

Вы и правда так думаете? :D Скомпилируйте, прошу Вас.

Автор:  igor [ Вторник, 05 Январь, 2010 23:27 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
Скомпилируйте, прошу Вас.
К сожалению (или к счастью :) ), я не практикую программирование на C++. У меня даже нет подходящего компилятора.
Интрига сохраняется :) .

PS: Даже если все другие языки программирования вдруг исчезнут, то и в этом случае я не стану программировать на C++. Адептов C++ прошу не принимать близко к сердцу. На всякий случай сообщаю, что "воспитывать" меня бесполезно :) .

Автор:  kemiisto [ Вторник, 05 Январь, 2010 23:30 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor, вот держите вывод. Будьте любезны. :D
Код:
value in [0, 5]
value in [6, 13]
value in [13, 26]
value in [26, 34]


А вот в Python, к слову, есть такая "фича". Называется сhained comparison. Но подводный камень тот ещё.
Цитата:
For expressions without side effects, a < b < c is equivalent to a < b and b < c. However, there is a substantial difference when the expressions have side effects. a < f(x) < b will evaluate f(x) exactly once, whereas a < f(x) and f(x) < b will evaluate it twice if the value of a is less than f(x) and once otherwise.

Автор:  igor [ Вторник, 05 Январь, 2010 23:42 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
igor, вот держите вывод. Будьте любезны. :D
Код:
 
Вот те раз! Неужели компилятор, которым Вы пользуетесь, настолько кривой! Не могу в это поверить.

Насколько я смог понять из цитаты из Питона, сокращённый вариант даже предпочтительней, так как value гарантированно будет вычислено компилятором только единожды.

Автор:  igor [ Вторник, 05 Январь, 2010 23:47 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto, а у Вас есть возможность скомпилировать этот пример другими компиляторами с языка C++? Интересно было бы сравнить полученные результаты. Интерстроновский компилятор, например, по слухам очень качественный.

Автор:  kemiisto [ Среда, 06 Январь, 2010 00:01 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
kemiisto писал(а):
igor, вот держите вывод. Будьте любезны. :D
Код:
 
Вот те раз! Неужели компилятор, которым Вы пользуетесь, настолько кривой! Не могу в это поверить.

Язык кривой, не компилятор. Проверял на Apple g++ 4.2.1 и MS VC++ 2008.

igor писал(а):
Насколько я смог понять из цитаты из Питона, сокращённый вариант даже предпочтительней, так как value гарантированно будет вычислено компилятором только единожды.

Ну да. Зато велика вероятность, что захочеться "улучшить" код, переписав с таким вот "сокращённым вариантом". А разница-то есть.

Автор:  kemiisto [ Среда, 06 Январь, 2010 00:12 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
kemiisto, а у Вас есть возможность скомпилировать этот пример другими компиляторами с языка C++? Интересно было бы сравнить полученные результаты. Интерстроновский компилятор, например, по слухам очень качественный.

Да не важно. В С/С++ нет такой штуки, как двойные неравенства.

Код:
if (0 <= value <= 5)

Что тут происходит (?):
  • Вычисляется значение выражения 0 <= value. true.
  • Вычисляется значение выражения true <= 5. То есть 1 <= 5. true.

Код:
if (6 <= value <= 13)

Что тут происходит:
  • Вычисляется значение выражения 6 <= value. false.
  • Вычисляется значение выражения false <= 13. То есть 0 <= 13. true.

Всё приплыли. Ну и так далее. Вот она "строгая" типизация во всей своей красе. Максисмум можно warning'а добиться про unsafe usage of bool type.

Автор:  igor [ Среда, 06 Январь, 2010 00:17 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
А разница-то есть.
Но её НЕ ДОЛЖНО БЫТЬ!!! Я скорее поверю, что все компиляторы кривые.

Немного поясню. Как бы мы не записали такое условное выражение, в любом случае компилятор на уровне машинных команд будет проверять эти два условия последовательно. В этом смысле оба варианта записи эквивалентны.

Автор:  igor [ Среда, 06 Январь, 2010 00:22 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
Код:
if (0 <= value <= 5)

Что тут происходит (?):
  • Вычисляется значение выражения 0 <= value. true.
  • Вычисляется значение выражения true <= 5. То есть 1 <= 5. true.
УЖОС!!! Вот это и называется кривой реализацией. Если компилятор работает именно так как Вы описали, то я просто в шоке от такого компилятора.

Автор:  kemiisto [ Среда, 06 Январь, 2010 00:23 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
kemiisto писал(а):
А разница-то есть.
Но её НЕ ДОЛЖНО БЫТЬ!!!

Отчего же? Если в a < f(x) < b, f(x) - функция с побочным эффектом, то разница будет. Один вызов против двух. Как и процитировано чуть выше.

Автор:  igor [ Среда, 06 Январь, 2010 00:30 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
Да не важно. В С/С++ нет такой штуки, как двойные неравенства.
Опаньки :D ! Если в языке двойных неравентсв нет, то компилятор не должен пропускать такие синтаксические конструкции. Иначе, про надёжность можно забыть. Хороший компилятор должен не только обеспечивать все специфицированные свойства и фенечки, но и пресекать всякую отсебятину.

Так что сюрпиз всё-таки есть. Но не со стороны языка, а со стороны компилятора. Настаиваю на этом.

Автор:  kemiisto [ Среда, 06 Январь, 2010 00:32 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
УЖОС!!! Вот это и называется кривой реализацией.

igor, это стандартное поведение. С++ International Standard ISO/IEC 14882:2003(E), 4.7 Integral conversions
Цитата:
4 If the destination type is bool, see 4.12. If the source type is bool, the value false is converted to zero and the value true is converted to one.

Автор:  igor [ Среда, 06 Январь, 2010 00:38 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
igor, это стандартное поведение. С++ International Standard ISO/IEC 14882:2003(E), 4.7 Integral conversions
Вот в этот момент у всех слушателей, мирно наблюдающих за нашей дружеской беседой, должно возникнуть смутное понимание того, почему я не программирую на C++ :wink: .

Автор:  igor [ Среда, 06 Январь, 2010 00:55 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

kemiisto писал(а):
Если в a < f(x) < b, f(x) - функция с побочным эффектом, то разница будет. Один вызов против двух. Как и процитировано чуть выше.
Очень тонкий момент, на который я не обратил внимание :? .

Надо бы запретить использовать в выражениях функции с побочным эффектом. В языке, который я сейчас разрабатываю, так и будет :wink: . Я уже предварительно продумал соответствующие проектные решения. Подробности попридержу пока при себе.

Автор:  Илья Ермаков [ Среда, 06 Январь, 2010 09:00 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
Если компилятор работает именно так как Вы описали, то я просто в шоке от такого компилятора.


Это не компилятор. Это нормальное его поведение.
Семантика записанной конструкции именно такая - сравнение числа с булевым результатом от второго сравнения, приведённым к 0/1.

Автор:  igor [ Среда, 06 Январь, 2010 11:28 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

Илья Ермаков писал(а):
Семантика записанной конструкции именно такая - сравнение числа с булевым результатом от второго сравнения, приведённым к 0/1.
Думаю, что проблема проистекает из того факта, что язык Си не видит отличий между целыми и логическими переменными. На самом нижнем уровне, конечно, всё можно представить целыми числами (даже вещественные числа :wink: - см. IEEE Standard 754). Но лично мне такая "мощь" в языке высокого уровня кажется по крайней мере странной.

Автор:  igor [ Среда, 06 Январь, 2010 11:49 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

igor писал(а):
Так что сюрпиз всё-таки есть. Но не со стороны языка, а со стороны компилятора. Настаиваю на этом.
После предоставленных мне разъяснений не вижу смысла продолжать "настаивать на этом" :) . Сначала нужно убрать "муть" из языка и его стандарта. (Так! Это не призыв, а скорее риторическое пожелание).

Кстати, Дарья Донцова случайно не принимала участия в создании стандарта языка C++?
Чем можно объяснить и оправдать очевидное противоречие между "в языке Си нет двойных неравенств" и "это стандартное поведение компилятора"?

Автор:  Илья Ермаков [ Среда, 06 Январь, 2010 12:20 ]
Заголовок сообщения:  Re: C++, очередной сюрприз

Да не двойное это неравенство!

А сравнение константы с результатом выражения; в силу дефектов типизации С++ вторым выражением может быть и логическое (сравнение), оно автоматически приводится к числовому.

В С же (до ISO-99 точно) bool вообще не было, так что вообще никаких приведений - обычная арифметика получалась :)

Дефекты синтаксиса и семантики.

А компиляторы нормальные, в плане соответствия языку.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/