Здравствуйте, LaptevVV, Вы писали:
LVV>Рекомендую!
Полистал немного. Об этом надо писать поэму, а не книжку в прозе.
#include <string>
int main() {
std::string s;
s += 48; // неявное приведение к char.
s += 1000; // а тут еще и с переполнением, очень неприятным
// на платформе с signed char.
s += 49.5; // опять-таки неявное приведение к char
}
Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
Здравствуйте, Pzz, Вы писали:
Pzz>Полистал немного. Об этом надо писать поэму, а не книжку в прозе.
Да там много интересного.
Вот грабли, на которые я ещё не наступал:
Pzz>Полистал немного. Об этом надо писать поэму, а не книжку в прозе. Pzz>
Pzz>#include <string>
Pzz>int main() {
Pzz> std::string s;
Pzz> s += 48; // неявное приведение к char.
Pzz> s += 1000; // а тут еще и с переполнением, очень неприятным
Pzz> // на платформе с signed char.
Pzz> s += 49.5; // опять-таки неявное приведение к char
Pzz>}
Pzz>
Pzz>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
Да.
Мне просто в голову такая хрень никогда не приходила! Ни разу в жизни такое не писал...
А оно вон оно чо, Михалыч!
Проверил на MinGW gcc 14.2 — компилируется!
Предупреждение выдает только на строку с 1000:
warning: overflow in conversion from 'int' to 'char' changes value from '1000' to '-24' [-Woverflow]
Даже на 49.5 — ничего не пишет!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
Pzz>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов. LVV>Да. LVV>Мне просто в голову такая хрень никогда не приходила! Ни разу в жизни такое не писал... LVV>А оно вон оно чо, Михалыч!
Там самая мякотка — в главе про неработающий синтаксис.
struct Timer {
int val;
explicit Timer(int v = 0) : val(v) {}
};
struct Worker {
int time_to_work;
explicit Worker(Timer t) : time_to_work(t.val) {}
friend std::ostream& operator << (std::ostream& os, const Worker& w) {
return os << "Time to work=" << w.time_to_work;
}
};
int main() {
// ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!
std::cout << w; // имя функции неявно преобразуется к указателю, который неявно преобразуется к bool
// будет выведено 1 (true)
}
Здравствуйте, so5team, Вы писали:
Pzz>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
S>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.
В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.
Pzz>Там самая мякотка — в главе про неработающий синтаксис. Pzz>
...
Pzz> // ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
Pzz> Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!
Pzz>
Ну, я как привык смолоду писать попроще, через равенство — так и пишу.
Сейчас приходится переучиваться на {}
Но вообще — да.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, LaptevVV, Вы писали:
LVV>Ну, я как привык смолоду писать попроще, через равенство — так и пишу. LVV>Сейчас приходится переучиваться на {} LVV>Но вообще — да.
Это я выдернул первое, что под руку подвернулось. Там много весёлого.
Я понимаю, что половина этого в Си тоже есть. Но в Си нет всех этих прекрасных автоматизмов, которые способны превратить простую и понятную ошибку в хитрую или запутанную.
Это ещё с сишечки по-моему так. В любом случае, компилятор тебе скажет, как минимум предупреждение, что одна переменная скрывает другую. Но, конечно, если у тебя при компиляции "кучи ненужных варнингов" (c) (tm), но будут грабли.
Pzz>Там самая мякотка — в главе про неработающий синтаксис.
Pzz>
Pzz>int main() {
Pzz> // ЭТО НЕ ВЫЗОВ КОНСТРУКТОРА!
Pzz> Worker w(Timer()); // предобъявление функции, которая возвращает Worker и принимает функцию, возвращающую Timer и не принимающую ничего!
Pzz> std::cout << w; // имя функции неявно преобразуется к указателю, который неявно преобразуется к bool
Pzz> // будет выведено 1 (true)
Pzz>}
Pzz>
Здравствуйте, Pzz, Вы писали:
S>>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.
Pzz>В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.
А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?
Здравствуйте, B0FEE664, Вы писали:
Pzz>>Полистал немного. Об этом надо писать поэму, а не книжку в прозе. BFE>Да там много интересного.
Мне еще вот такое очень понравилось:
// пример взят из блога https://mohitmv.github.io/blog/Shocking-Undefined-Behaviour-In-Action/int main() {
char buf[50] = "y";
for (int j = 0; j < 9; ++j) {
std::cout << (j * 0x20000001) << std::endl;
if (buf[0] == 'x') break;
}
}
Тут компилятор решает вынести умножение из тела цикла. Заменяет ++j на j += 0x20000001, ну и верхнюю границу, девятку, тоже умножает на 0x20000001. А что, имеет право, целочисленное переполнение для знаковых типов — это UB. В итоге цикл на 9 оборотов становится бесконечным.
Здравствуйте, Marty, Вы писали:
Pzz>>В сишечке это не имеет таких последствий. Си, всё-таки, простой, обозримый, компактный язык. К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.
M>А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?
Здесь — ничем.
А вот когда к сишным (весма вольным и дурным) правилам преобразования типов добавляется сипплюсплюсная идея вложить в тип глубокий смысл, позволив через оверлоадинг приделать к разным типам разное поведение для одинаково выглядещих действий, жизнь становится уже весьма забавной.
Здравствуйте, Pzz, Вы писали:
M>>А какие последствия будут в приведённом случае? К строке прибавится символ? Чем это отличается от сишечного?
Pzz>Здесь — ничем.
Pzz>А вот когда к сишным (весма вольным и дурным) правилам преобразования типов добавляется сипплюсплюсная идея вложить в тип глубокий смысл, позволив через оверлоадинг приделать к разным типам разное поведение для одинаково выглядещих действий, жизнь становится уже весьма забавной.
Дурные правила преобразования типов работают только для интегральных типов и плавучки. Это полностью наследие сишечки. Для типов, в которые вложен глубокий смысл, всё весьма строго.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Матерную поэму. В этой поэме должно быть много красивых, выразительных и поэтичных русских матерных слов.
S>>Эка вы в адрес своей любимой ламповой сишки раздухарились! Прям любо-дорого.
Pzz>В сишечке это не имеет таких последствий.
Вот объясните мне, а то я не понимаю это что: глупость, двойные стандарты или и то, и другое?
Ибо когда в Си из-за дебильных правил приведения типа хз какой char автоматически и неявно генерируется из double-литерала, то это OK.
А вот когда в С++ в точности тоже самое происходит из-за тех же самых (именно что тех же самых, унаследованных из Си) правил -- то это уже мать-мать-мать-перемать.
Ну вот как это в одной башке уживается?
Pzz>К тому же с каждого, кто рискует программировать на чистом Си, мироздание берет подписку, что все отстреленные ноги за счет стрелка, претензии к безопасности пулемета не принимаются. Что несколько дисциплинирует, по крайней мере, выживших.
Вы, видимо, забыли (а может никогда и не знали) старый афоризм: Си позволяет вам выстрелить себе в ногу, в C++ это сделать сложнее, но когда вы это таки сделаете, то вам отрывает нахрен сразу обе ноги.
Ну и чтобы еще набросить на вашу пустую седую голову: в современном С++ хотя бы можно написать s += char{49.5} и получить ошибку компиляции. А вот что здесь может предложить Си?
Здравствуйте, so5team, Вы писали:
S>Ну и чтобы еще набросить на вашу пустую седую голову: в современном С++ хотя бы можно написать s += char{49.5} и получить ошибку компиляции. А вот что здесь может предложить Си?
Мы с вами уже договаривались, что либо вы не хамите, либо мы не общаемся.
Здравствуйте, LaptevVV, Вы писали:
LVV>Рекомендую!
Вспомнилось. Во времена Фортрана литературы "Грабли в Фортране" было полно. Мы даже что-то проверяли, когда учились. Порчу константы или беспорядочное использование COMMON, особенно безымянных. Зато в реальной работе граблей избегать удавалось.
А на C/C++ мне довелось написать совсем немного кода. Всякие там JNI и вставки к фортрановскому проекту.
Но судя по опыту работы с Фортраном, такая литература должна быть полезной.
P>Вспомнилось. Во времена Фортрана литературы "Грабли в Фортране" было полно. Мы даже что-то проверяли, когда учились. Порчу константы или беспорядочное использование COMMON, особенно безымянных. Зато в реальной работе граблей избегать удавалось.
Да, это я тоже знаю... P>А на C/C++ мне довелось написать совсем немного кода. Всякие там JNI и вставки к фортрановскому проекту. P>Но судя по опыту работы с Фортраном, такая литература должна быть полезной.
Она очень полезна.
Для начинающих — откровение увидеть, как сложение 2 положительных становится отрицательным.
А в этой книжке поглубже, для мидлов.
Неявные преобразования — зло абсолютное.
Теперь у меня для студентов есть аргументированный источник примеров.
Не совсем уж тривиальных.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!