LINUX.ORG.RU
ФорумTalks

Почему жабисты и растаманы лучше С++ников

 , ,


5

12

Кажется я понял основную причину, отчего у С++хейтеров постоянно исключения в деструкторах сыпятся и все падает. Почему у них память принципиально течет, и все сегфолтится. У них просто логика античеловеческая. Всё, что не запрещено, то разрешено, или все что не разрешено то запрещено - это две большие разницы, для этих существ неразличимые.

Показываю на примере undefined результата в случае переполнения int в С в компиляторе здорового человека и в компиляторе курильщика.

В компиляторе здорового человека под undefined behavior в случае переполнения int подразумевается, что человек напишет программу так, что переполнения int не будет потому что он предупреждён. Поэтому компилятор может применить к выражениям оптимизации, которые небезопасны в случае переполнения.

В компиляторе курильщика принято считать что раз у нас в стандарте написано что UB, значит мы имеем право генерировать непредсказуемые результаты в ходе оптимизаций.

А это не одно и то же. Оптимизации здорового человека не предполагают нарушения логики работы программы. Если у вас написано x&y то операция И должна быть выполнена. Там нет переполнения. Её надо выполнить, даже если по отдельности икс и игрек переполнились. Вы не можете убрать операцию только потому, что у вас int в качестве аргумента. Выражение должно давать правильный результат при допустимых аргументах, вот что означает undefined behavior у int при недопустимы аргументах.

Оптимизации курильщика же предполагают что выражение может дать непредсказуемый результат всегда. Они просто не понимают, почему так нельзя. «в стандарте написано». Ученым до сих пор непонятно, почему компиляторы курильщика не заменяют все выражения, содержащие int, на вызов random(). Возможно, курильщики просто не знают о существовавнии этой функции и генерят рандом руками на лету.

А теперь эти идиоты добрались до gcc и сломали его. Это печально. Если бы они так кошмарили свою жабку или раст, это было бы смешно и забавно. Но увы, зло пришло и на нашу землю.

А что касается исключений в деструкторах и прочей байды. Так это то же самое. Они просто не понимают почему нельзя. Не запрещено же. Они реально не понимают, зачем существует та или иная штука. Поэтому кстати у них и шаблоны атакуют и bloatят код. Люди просто не могут не «шаблонить». Зомбачи.

Поэтому жабакодеры и растаманы лучше С++ников. С++ гавно а жаба рулит и раст рулит. GC в каждый дом. Исключения в каждый деструктор. Потому что надо жить не по лжи.

Перемещено tailgunner из development

☆☆☆
Ответ на: комментарий от anonymous

В единственной приведенной тут строке не видно ub, кроме условного, причем условие не соблюдается.

Так что либо UB где-то в контексте, либо таки баг.

anonymous
()
Ответ на: комментарий от anonymous

в логических построениях ты не силён, но я, кажется, всё таки распарсил.

немного выше в треде бредили про связь уб с оптимизациями. она действительно есть: реализовать определённое поведение при переполнении инта (а тем более, как ты наверное хочешь, эмулировать поведение х86) может быть не так уж и дёшево. поэтому разрешили творить что угодно. и каждый творит. в меру своей испорченности. в частности, гцц выбрасывает код как только понимает что наступил на уб.

anonymous
()
Ответ на: комментарий от anonymous

результат этого выражения — <ub> (можешь рассматривать его как аналог бесконечности) хоть с &, хоть без

С чего ты решил, что UB == «генерь рандом» - в него так же входит и «генерь то, что написано».

И теперь если мы берём логику «уб == ошибка», то почему об этой ошибки компилятор не сообщил. А если «уб == как написал юзер и вся логика на юзере», то какого хрена ты сгенерил не то, что написал юзер и ПОВЕСИЛ НА НЕГО ЗА ЭТО ОТВЕТСТВЕННОСТЬ?

Т.е. проблема не в том, что компилятор сгенерил говно - он сгенерил это говно ЗНАЯ, вернее ОПРЕДЕЛИВ( по твоей же логике) УБ за ОШИБКУ. И именно в этом проблема, а не в трактовке УБ.

anonymous
()

применить к выражениям оптимизации, которые небезопасны в случае переполнения
раз у нас в стандарте написано что UB, значит мы имеем право генерировать непредсказуемые результаты в ходе оптимизаций
А это не одно и то же.

Если ещё не читал, прочитай, может пукан подостынет:
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_14.html
http://blog.llvm.org/2011/05/what-every-c-programmer-should-know_21.html

А теперь эти идиоты добрались до gcc и сломали его.

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

Manhunt ★★★★★
()
Ответ на: комментарий от anonymous

fix

не так уж и дёшево == не так уж и дёшево на некоторых платформах

anonymous
()
Ответ на: комментарий от anonymous

там 100% баг. я не могу его изолировано повторить, но «в сумме» в результате видимо инлайнинга уничтожается И. причем уничтожается жёстко. а кстати я даже догадывась отчего. gcc видит первое И в инлайновой функции, и видит второе И в функции не-инлайновой. походу он инлайнит вторую функцию хотя бы частично и удаляет оттуда второе и. вторая функция живет только в cpp файле и наружу не торчит.

f(g(h()))

если в f и h используется И то оно каким-то хером пролезает сквозь оптимизацию intов и уничтожается несмотря на операции в g

gcc походу делает перестановки операций сложения и логических. вот гнида.

ckotinko ☆☆☆
() автор топика
Последнее исправление: ckotinko (всего исправлений: 3)
Ответ на: комментарий от ckotinko

напомни мне, сколько будет <бесконечность> + 10

anonymous
()
Ответ на: комментарий от ckotinko

там 100% баг. я не могу его изолировано повторить

вот и начни с воспроизведения ошибки и определения реальной причины ее возникновения, а сопли на форуме возить - это все умеют

shty ★★★★★
()
Ответ на: комментарий от ckotinko

Давай сначала проясним кое-что. Считаешь ли ты багом в компиляторе что эта программа печатает «value is: 0» ?

#include <stdio.h>
#include <stdlib.h>

void bar(int x) {
    printf("value is: %d\n", x);
}

void foo(int a) {
    if (a * 8 == 0) {
        return;
    }
    bar(a * 8);
}

int main() {
    int z = atoi("536870912");
    foo(z);
}
pftBest ★★★★
()
Ответ на: комментарий от anonymous

в него так же входит и «генерь то, что написано»

и многое другое. вот здесь www.linux.org.ru/add_comment.jsp?topic=13428281&replyto=13428679 я привёл все возможные варианты.

коммерческие компиляторы выбирают первый вариант — «генерь рандом». возможно, какие-нибудь компиляторы для военных пользуются последним вариантом — «уб == ошибка»

anonymous
()
Ответ на: комментарий от ckotinko

Я же говорю - это антилюди. У них логика другая в принципе.

Открой стандарт (даже не на с++, на ссаный си), и там английским по белому написано:

5.1.2.3 Program execution

The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant.

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects,11) which are changes in the state of the execution environment. Evaluation of an expression may produce side effects. At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place. (A summary of the sequence points is given in annex C.)

In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its
value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

When the processing of the abstract machine is interrupted by receipt of a signal, only the values of objects as of the previous sequence point may be relied on. Objects that may be
modified between the previous sequence point and the next sequence point need not have received their correct values yet.



То есть с самого начала, по замыслу авторов стандарта, речь идёт не о каком-то там «макроассемблере», а об абстрактной плохо определенной херне, которую компилятор вертит как хочет. Когда ты сделал UB - считай, что абстрактную машину распидорасило, кровь, кишки. Вот такой ублюдочный по определению язык этот ваш си и с++.

Manhunt ★★★★★
()
Последнее исправление: Manhunt (всего исправлений: 1)
Ответ на: комментарий от anonymous

Уважаемый балабол. Твои потуги вокруг моей силы имеют ровно ноль «силы» т.к. не имеют никаких оснований под собою.

А как мы уже знаем высер * 0 = 0. Зачем ты нарушил своё же правило, которым пытался объяснить УБ?

Далее пошел какой-то не относящийся к теме высер. Отвечая мне - ты отвечаешь мне. Зачем ты отвечая мне не отвечаешь мне, а отмечаешь треду? Вот и отвечай треду.

Твои потуги мне рассказать про «зачем там УБ» глупы - т.к. во-первых из них ничего не следует, а во-вторых ты просто подтвердил мои слова.

В своей потуге объяснить поведения компилятора - ты УБ принял как «нельзя». И если стандарт определял «нельзя», то зачем он не сказал это прямо? Если это «не так дёшево» - запрети эту операцию. В чём проблема?

Т.е. стандарт не стал её запрещать - он снял с себя ответственность. Дак какого хрена ты апеллируешь к стандарту? СТАНДАРТ НЕ ОТВЕЧАЕТ ЗА УБ И ЕГО ТРАКТОВКУ.

Т.е. ссылка на стандарт в рамках «трактовки поведения УБ» говорит лишь о том, что ТВОЁ ПОВЕДЕНИЕ ВАЛИДНО В ОТНОШЕНИИ СТАНДАРТА. НО Я С ЭТИМ НЕ СПОРЮ.

Я ОБСУЖДАЮ ИМЕННО ТО, ПОЧЕМУ КОМПИЛЯТОРЫ ТАК ЕГО ТРАКТУЮТ. ИМЕННО ПОДХОД К ТРАКТОВКЕ.

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

Определить за рандом - это определённое поведение. Вот ведь нежданчик, да? Но ничего, я думаю лет через 50 ты сможешь это сознать, а пока жуй.

anonymous
()
Ответ на: комментарий от anonymous

высер * 0 = 0

тебе неизвестно понятие бесконечности. поэтому рассуждать на этот счёт ты не имеешь права

anonymous
()
Ответ на: комментарий от anonymous

Если это «не так дёшево» - запрети эту операцию. В чём проблема?

запретить переполнение?

anonymous
()
Ответ на: комментарий от pftBest

да, это абслютно точно баг. в компиляторе, в головах разработчиков и т.д. ну хотя бы потому что atoi это функция из непонятно откуда.

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от Manhunt

об абстрактной плохо определенной херне, которую компилятор вертит как хочет

in which issues of optimization are irrelevant.

вторая попытка.

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от red75prim

как минимум, от нуля(включая) до 8191. ну так должен работать нормальный оптимизатор - вычислимое вычислять, объединимое объединять(-ffast-math например).

но нельзя например (x*y)&z преобразовать в (x&z)*(y&z). ну нет такой перестановки. в теории нет.

ckotinko ☆☆☆
() автор топика

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

Казалось бы, такая простая тема. Вася сказал пети «делай как хочешь» - Петя сделал дерьмо. Алёша спросил у Пети «почему ты сделал дерьмо?» - на что петя ему отвечает «но Вася мне сказал „делай как хочешь“».

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

И именно об этом тема. Не о том, соблёл ли Петя условие Васи. А том «почему Петя поступил так?». И логична ли апелляция Пети к тому, что «Вася не сказал „не дерьмо“ - значит он хотел, чтобы я сделал дерьмо». И я прошу людей подумать - ведь, если бы Вася хотел того, чтобы Петя сделал дерьмо - он бы так и сказал.

В рамках стандарта, конечно, ситуация ещё сложнее и далеко не в пользу Пети. Всё это я разобрал, но похоже зря. Это оказалось слишком сложно - думаю сейчас станет попроще.

anonymous
()
Ответ на: комментарий от pftBest

ооооо. да, молодец, уел.

теперь действительно можно сказать что жабисты пробрались в гцц.

сумасшедшие придурки. надо что-то с этим делать. реально люди с античеловеческой логикой.

ckotinko ☆☆☆
() автор топика
Ответ на: СТАНДАРТ НЕ ОТВЕЧАЕТ ЗА УБ И ЕГО ТРАКТОВКУ. от anonymous

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

Действительно - отвечая «кукареку» мне на пост - ты показываешь всю суть моего общения с подобными «экспертами».

anonymous
()
Ответ на: комментарий от ckotinko

я предлагаю генерить код, который отражает написанное в программе. это что, невыполнимое требование?

Если в программе написана херня (т.е. UB), то в сгенеренном коде тоже будет херня (ведет себя невменяемо, а не так, как мечталось программисту). Язык Си предполагает именно такое «отражение».

Кстати, о растаманах, у них по этому поводу баттхерт не хуже твоего, они не хотят чтобы в расте было так же хрупко, как в Си:
https://internals.rust-lang.org/t/comparing-dangling-pointers/3019/31

The LLVM Reference manual http://llvm.org/docs/LangRef.html#undefined-values disagrees:

This example points out that two ‘undef‘ operands are not necessarily the same. This can be surprising to people (and also matches C semantics) where they assume that “X^X” is always zero, even if X is undefined.

x could have a different value every time (if the «undef» is intended in the LLVM way).


Right, I know that undef can be different each time. What I was trying to say is that it would be useful if LLVM offered a «fix(V)» operator/intrinsic/whatever which, if V is undef, yields a random (but no longer undef) value, but otherwise yields V. As far as I know, though, no such operator exists.


I find C's strict aliasing rules unfortunate, because I think they violate most people's mental model of how the computer works and what should be allowed. Basically, people should be able to think of the machine as a kind of simple turing machine that runs along and loads and stores data, and strict aliasing rules break that.

Manhunt ★★★★★
()
Ответ на: комментарий от anonymous

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

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от ckotinko

но нельзя например (x*y)&z преобразовать в (x&z)*(y&z)

С точки зрения теории типов ⊥&b = ⊥. Так что, по логике, все значения после вычисления ⊥&b - фантазии компилятора.

red75prim ★★★
()
Ответ на: комментарий от Manhunt

я учился в советской школе и знаю советские правила математики и логики. UB для int в компиляторе здорового человека всего лишь открывает возможности для оптимизации умножений, сложений и то в очень ограниченом пространстве. Есть непереставимые операции. Ну просто они есть, так у здоровых людей. Вот то что написано в llvm это атас.

Это я не знаю. Это как ссылаться на закон о поедании говна выписаный ким хрен ином и говорить что говно есть полезно и здорово. Люди берут и ломают нахер компилятор потому что вот это принудительно постулированное UB даже там, где его нет - это же придется форсить в компиляторе. Нормальная в моем понимании оптимизация выражений такого не даст получить. ну хотя бы потому что XOR в обратную сторону не работает, иначе бы криптографии не было.

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от ckotinko

об абстрактной плохо определенной херне, которую компилятор вертит как хочет
in which issues of optimization are irrelevant.

вторая попытка.

1. Вдумчиво перечитай все четыре процитированных абзаца, а не останавливайся на первой фразе.
2. Я об оптимизациях ни слова не сказал.

Manhunt ★★★★★
()
Ответ на: комментарий от ckotinko

Непонятно что у тебя там с сабжевым случаем, но вообще характерно, что распальцованный сишник только теперь открыл то что написано в начале стандарта с 99-го года (или раньше, лень искать старую версию).

С баррхертом вас :D Непонятны только наезды на раст и жабу - там как раз сюрпризов куда меньше. Вот тебе бы раст доставил меньше боли.

anonymous
()
Ответ на: комментарий от ckotinko

знаю советские правила математики и логики

Млять, ну до чего же эпично!

Ой, чую тема взлетает. Самого Царя с пары-тройки ответов расколбасило в пух и прах.

Иду за новой порцией попкорна.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от Manhunt

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

к слову. как я понимаю gcc убил операцию И т.к. решил что биты которые она нулит так нулевые. я такую штуку знаю, если что.

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

ckotinko ☆☆☆
() автор топика
Последнее исправление: ckotinko (всего исправлений: 1)
Ответ на: комментарий от ckotinko

право переполнять int не следя за ним говорит лишь о небольшом классе оптимизаций которые становятся допустимы

Покажи обоснование этому. Ты ведь не придумал это сам, это написано в доках, правда?

anonymous
()
Ответ на: комментарий от ckotinko

UB для int в компиляторе здорового человека

Мыль, которую стараюсь до тебя донести: это не в компиляторе проблема, а в стандарте (то есть в спецификации языка). Стандарт должен был регламентировать, какими могут быть последствия «плохих» операций над int-ами. Стандарт вместо этого регламентировал UB.

Язык, в котором вместо Undefined Behaviour будет Undefined Value — это другой язык. Не Си. Вот и всё.

Manhunt ★★★★★
()
Ответ на: комментарий от ckotinko

я предлагаю генерить код, который отражает написанное в программе. это что, невыполнимое требование?

Ну так используй -O0, в чем проблема?

Stil ★★★★★
()
Ответ на: комментарий от Manhunt

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

пусть есть некое выражение. в некотором диапазоне входных значений его вычисление наиболее эффективным способом приводит к ошибкам. мы декларируем что в угоду скорости мы не гарантируем корректного вычисления выражения в этом диапазоне. НО в допустимом диапазоне входных значений мы гарантируем корректное вычисление результата выражения. в этом суть оптимизации.

в треде банда жабистов утверждает, что корректное вычисление результата не гарантируется в принципе никогда. потому что тут написано int а значит у нас майдан, все скачем. UB - только за пределами некоторого допустимого интервала. интервал может съужаться в зависимости от операций конечно. т.е. a*b+c*b может стать (a+c)*b но не может стать a+c*b. логику программы нарушать нельзя.

жабисты говорят что раз они увидели слово UB то оно будет везде.

вообще для тупых анонов: вы не имеете права на UB при допустимых входных значениях. UB - только при переполнении. без переполнения UB быть не должно

ckotinko ☆☆☆
() автор топика
Последнее исправление: ckotinko (всего исправлений: 1)

Самые однополые любовники - это обэже-сишники. Их оружие - водяной пистолетик в виде самотыка

TooPar
()
Ответ на: комментарий от Stil

вообще для тупых анонов: вы не имеете права на UB при допустимых входных значениях. UB - только при переполнении. без переполнения UB быть не должно

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от ckotinko

Ты так _творчески_, я бы сказал по-царски, пишешь, что тебя трудно понимать. Давай я помогу сформулировать твою мысль.

int index = 8191& int(8192.0f*angle/M_PI);

Дано выражение, в котором на некоторых входных данных возникает UB - переполнение int. ТС гаранирует что на его входных данных переполнения нет, а значит генерировать лажу компилятор не имеет права.

Всё, это так просто и сразу можно согласиться. Только неизвестно, связана ли твоя лажа с этим потенциальным переполнением, скорее всего нет. А что там на самом деле - гадать без кода бессмысленно.

anonymous
()
Ответ на: комментарий от anonymous

что мне тебе показать? 60к строк? 1к строк? невырезаемо.

у меня в функции написано было

void myclass::foo(int angle,....) {
  ...
  int x = 8191 & (angle-another_angle);
  if (x >= 0) {
  }
}

все типы int. angle получался от 8191&int(atan2(y,x)*k) но через пеньколоду;

и пока я не добавил else я не понимал, почему код не вызывается.

ckotinko ☆☆☆
() автор топика
Ответ на: комментарий от ckotinko

ты утверждаешь, что у операции есть две зоны «доверенный интервал» где все хорошо, и «все остальное» где UB

где это написано? Ни в описании компилятора, ни в стандарте, дай ссылку или кейворды для гугления?

то что ты говоришь - сложная оптимизация, если ее реализация обязательна - где-то это должно быть явно написано

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от eao197

Зачем мне с тобою, некомпетентной балаболкой, которая даже не программист, спорить? Таких как ты тут 99%, но при этом вы самые активные.

С чего меня должно расколбасить? Кто мне что-то может ответить, ты что ли? Другие «эксперты» из треда? Я таким множу на ноль не врубая даже мозг - на автопилоте.

Да и какой попкорн, если все, кто пытался со мною спорить уже слились? Один пока что отвечает, но он уже сломался. Он рассчитывает на отклик в аудитории. Это же за какое говно он считает вас, и лично тебя, что позволяет себе аргументацию уровня «ты неправ».

anonymous
()
Ответ на: комментарий от anonymous

я правда не могу взять и скопировать код. во первых это код с работы. во вторых там непонятно сколько копировать. баг не сразу триггерится.

как он вызывается:

class LOL {
   int b;
   void lol(int a) {
       int d = 8191&(b-a);
       if (d >= 0) { }
       b = a;
   }
}
int foo(double a) {
    return 8191&int(a);
}
int bar(LOL * lol, int a) {
    lol->lol(foo(a));
}
пропадает при переносе функции в другой файл. это не UB, это баг. такая «оптимизация» недопустима. логическое И и вычитание некоммутативны. тьфу неассоциативны.

ckotinko ☆☆☆
() автор топика
Последнее исправление: ckotinko (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.