Блог пользователя balalaika

Автор balalaika, история, 6 недель назад, По-английски

Inspired by this blog

I already gave answer there but it struck me that it can be nice educational blog. Though main reason I write this is training English-writing.

I will refer to this document which is the closest I know to C++23 standard.

Disclaimer: Never mix several increments/decrements in single expression (even if each operation performed on different variables) — it is just looks ugly almost always and it is harder to read.

Why exactly expression ++x + ++x is UB?

https://godbolt.org/z/qWbKfP9Gj. clang/gcc gives 13, msvc gives 14.

Let's explore how standard requires to calculate expressions. 6.9.1 is all about that. In particular, 6.9.5 introduces term full-expression with examples. For simplification let's say that every code between ; (but not only they) is full-expression:

int f();

int main() {
    std::cout << 2 + 2 << std::endl; // Whole line is full-expression
                                     // 2 + 2 itself not full-expression
    return f(); // Whole line is full-expression
}

6.9.8 introduces term sequenced before/after: A is sequenced before B meaning that every computation and side-effect needed for A is executed strictly before every computation and side-effect of B. And so defined sequenced after. And there introduced terms unsequenced and indeterminately sequenced: A and B unsequenced meaning that neither A is sequenced before B not B is sequenced before A. Therefore, evaluation of A can overlaps with evaluation of B. A and B indeterminately sequenced meaning that either A is sequenced before B or B is sequenced before A but there is no requirements about which is true.

And go to 6.9.10. There two things to be noted. First, any two expressions are unsequenced if standard doesn't says otherwise. So all cases of sequenced/indeterminately expressions must be explicitly defined in standard. Examples:

  • 6.9.9 All computations and side-effects of full-expression are sequenced before any computation or side-effect of next full-expression. Meaning lines of code executed in order:)
  • 7.6.1.6.1. i++. Obtaining value is sequenced before incrementing.
  • 7.6.14. left && right. Evaluation of left is sequenced before right. Moreover evaluation of right is taking place only if left is true.
  • 7.6.19.1. a = b. Evaluation if b is sequenced before a.
  • 7.6.1.3.7. Function call f(a, b). a and b are indeterminately sequenced. Fun fact: this appeared in C++17. So before C++17 argument evaluations were unsequenced.

Second thing to be noted from 6.9.10 is if side-effects of A unsequenced with side-effect/computation of B and same memory location is used then we got UB.

And this is exactly a case with ++x + ++x: side-effect of both increments modifying same object x, both increments evaluate this very object and standard says nothing about which of increments is sequenced first.

But there is operator precedence, isn't it?

Yep, but it is not about order of evaluation of operands. It is about evaluation of full-expression. operand evaluation still can be unsequenced.

int x = y++ + z++; // y++ is evaluated to y, z++ is evaluated to z. 
                   // Both increments can be executed in any order (even simultaneously)
                   // But x is evaluated to y + z
std::cout << a() << b() << c(); // c() can be evaluated before a() or even at the same time, but result is printed strictly after both a() and b()

Bonus: a+++++b what it is?

If you think that it is (a++)+(++b) because this is only well-defined expression then you wrong:)
5.4.3 If we not talking about raw string literals or <:: then we always take longest possible token even if it produces ill-formed program. So it is parsed as tokens a ++ ++ + b and it is compilation error.

If you have some good ideas about another C++ educational let me know.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +9
  • Проголосовать: не нравится

Автор balalaika, история, 7 лет назад, По-русски

Всем привет!

15 апреля 2018 года внезапно в МИЭТе прошла VI личная олимпиада по программированию, посвященная Юрскому Периоду.

Она доступна для свободного прорешивания по ссылке: VI Личная Олимпиада МИЭТ.

Задачи для вас были подготовлены balalaika, Samurai_X, igorrrain и zatinatscky.ivan.

Контест по большей части простой, двухзвездочный по местным меркам, но мы надеемся, что вы найдете для себя интересные задачи.

Возможно в конце месяца выложим контест в тренировки.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +16
  • Проголосовать: не нравится

Автор balalaika, история, 7 лет назад, По-русски

Напоролся на такой баг:

Мини-несоответствие, вообще на самом деле все равно даже, но может кого заинтересует...

Полный текст и комментарии »

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

Автор balalaika, история, 8 лет назад, По-русски

Доброго времени суток!

Возникла такая ситуация, что в один прекрасный день (12 апреля) обновились две системы: Ejudge и Полигон. После чего сломался импорт из Полигона в Ejduge. Стали вываливаться ошибки следующего вида:

problemName mismatch: <tr>: miet-2017-05, <td>:
miet-2017-05 (да, это именно на новой строке, только еще с кучей табов)

Поскольку системы обновились почти одновременно, мне сложно однозначно судить, на чьей стороне возникла проблема. Но больше подозреваю Полигон, поскольку откат Ejdug'а на старую версию не помог (хотя импорт конечно ejudg'а, поэтому и не могу точно сказать).

Эту же ошибку еще отписал в группу ВК, посвященную ejudg'у (да, она есть), пока ответа нету.
Пожалуйста, помогите!)

Полный текст и комментарии »

  • Проголосовать: нравится
  • +20
  • Проголосовать: не нравится

Автор balalaika, история, 8 лет назад, По-русски

Люди, шарящие в ejudge. Пишу сюда, ибо регистрация на форуме ejudg'а ныне закрыта, и там тему создать не могу.
Я нормально установил ejudge , подгружаю без проблем задачи с полигона, e-mail рассылку завел, все языки нормально завелись, но:

1) Mono C# считается небезопасным языком, и если включить безопасность, то для участников этот язык недоступен

2) При выключенной безопасности при посылки кода на шарпе выдается следующая ошибка:

/home/judges//compile/scripts/mcs: 32: /home/judges//compile/scripts/mcs: [[: not found

Compilation process timed out

Я глянул соответствующий файл, ругань идет на эту строку

[[ "${EJUDGE_FLAGS}" = "" ]] && EJUDGE_FLAGS="-optimize+"

Этот файл я никак не менял после установки ejudg'а. И плюс компиляция и запуск из терминала идет вообще безо всяких проблем. Сижу уже три дня, никаких адекватных идей не пришло. Переустановка (и компилятора, и ejudg'а) ничего не дала. Помогите, люди добрые, пожалуйста!

Linux Ubuntu 16.04 LTS (64-bit)
Mono C# 4.2.1.0

P.S. Если никто не в курсе, то можно ли как-то связаться с разработчиками, чтоб у них проконсультироваться?

Полный текст и комментарии »

  • Проголосовать: нравится
  • +3
  • Проголосовать: не нравится

Автор balalaika, история, 8 лет назад, По-русски

Издревле повелось, что в строковом представлении дробных числах роль разделителя целой от дробной части играет символ точка. И в плюсах код а-ля:

double d;
cin >> d;
cout << d;

считает и выведет дробное число с точкой, если на вход подастся строка "2.5". Однако в шарпе (насколько мне известно, еще в FPC, поправьте, если я ошибаюсь) символ, который будет разделителем, определяется настройками ОС. В нашем случае, если на вход подать строку "2.5" следующим кодом:

double d;
d = double.Parse(Console.ReadLine());

то выбросится исключение, поскольку с точки зрения шарпа, в дробных числах разделителем должна быть запятая. И наоборот, код:

Console.WriteLine(2.5);

выведет строку "2,5", что не принимается тестирующей системой за дробное число. И приходится делать извращения вроде:

double d;
d = double.Parse(Console.ReadLine().Replace('.', ','));
Console.WriteLine(d.ToString().Replace(',', '.'));

Есть ли в шарпе иные способы обхода таких ситуаций (System.Threading не предлагать — CF справедливо блокирует действия записи в этом модуле)? И возможно ли изменить настройки ОС на сервере, чтобы не приходилось вообще обходить это?

Да, шарп + олимпиадное проганье = жесть, но все равно интересно.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +24
  • Проголосовать: не нравится