LINUX.ORG.RU

gcc-8 совсем поломанный

 


3

7

Я так понимаю в последних версиях gcc хипстеры вообще всё сишку решили сломать. Хотя пишут статейки что C никогда не был портабельным ассемблером, но ведь использовали его так и куча кода накопилась. Теперь этот весь код сломан. Например сброс знака по (a & 0x7fffffff) не работает и много всего вообще теперь не работает и писать теперь надо как на плюсах. И страшно бояться любого UB так как оно будет страшно падать на ровном месте и 2+2 будет 5. Особенно это опасно, если лет 30 устоявшиеся методы для решения задач были, и эти чувырлы с UB головного мозга это всё радостно ломают. Я так понимаю это делается специально, чтобы кому-то не было скучно на работе, а реального толку 0. Какой сейчас более-менее адекватный gcc, 5.4? Шланг не предлагать, он никогда не был компилятором, вообще. Это они весь сыр-бор и начали. Я так понимаю реально там полезное сейчас только в C++ делают, в C только ломают.

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

А еще лучше код вообще не писать. Я не люблю, когда компилятор пытается меня нагнуть, предлагая переписывать старый работающий логичный код, заменяя на нелогичный бред. А еще идиоты, пихающие рапоследний багнутый компилятор в дистрибутив и выпиливающие нормально работающие, заставляя ставить сторонние тулчейны. Я понимаю что ломать работающее это модно и молодежно, так как чинить сломанное это уже не круто, но по-моему это уже беспредел. Когда они уже угомонятся? Наплодили еще макак, написать пару строчек не может, зато про UB всё знает... все вместо того чтобы фичи писать сидят с одного на другой стандарты переходят и на компиляторы надрачивают... :(

slapin ★★★★★
() автор топика
Ответ на: комментарий от proud_anon

Проверено, не работает. Не работает даже так

(int)((unsigned)a & 0x7fffffffU)
возвращяет число без изменений. Ловится ассертом. Думаю что они насильно протаскивают знаковый бит или как-то так. gcc-6.4 полёт нормальный. Хоть не самый лучший компилятор, но хоть не настолько всё плохо. Всё познается в сравнении...

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

У меня нет под рукой 8.2, но вот я проверил на онлайн-компиляторе: https://godbolt.org/z/a5VMVm

int myabs(int num) {
    return num & 0x7FFFFFFF;
}

Компиляция:
myabs:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        and     eax, 2147483647
        pop     rbp
        ret

Компиляция с -O3:
myabs:
        mov     eax, edi
        and     eax, 2147483647
        ret


Причём нет различий с 6.3

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

А еще лучше код вообще не писать.

Всем станет лучше (в т.ч. и тебе), если ты перестанешь писать код.

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

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

#include <stdio.h>

int foo(const char *s)
{
        int r = 0;
        while(*s) {
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                s++;
        }
        return r & 0x7fffffff;
}
int foo2(int c)
{
        return c & 0x7fffffff;
}

int main()
{
        int result = foo("simple simple some words whatever");
        printf("result: %d %08x\n", result, result);
        result = foo2(-100);
        printf("result: %d %08x\n", result, result);
        return 0;
}

Вывод:

result: -369875866 e9f42466
result: 2147483548 7fffff9c

Вот такая вот странная фигня.

slapin ★★★★★
() автор топика
Ответ на: комментарий от shdown

Разработчики компилятора стремятся нагадить везде, где стандарт не написал, что так можно. Проактивное вредительство - это новая фишка, да.

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

Дык может вам всем просто сдохнуть вместе с хипстанутыми разработчиками и оставить нормальных людей в покое?

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

Ага, с -O тоже не проявляется, осталось найти багнутую оптимизацию.

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

Вывод:

result: -369875866 e9f42466
 result: 2147483548 7fffff9c
Вот такая вот странная фигня.

Ты хоть сам знаешь, какой он должен быть?

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

ну вот точно не отридцательный.

Каноничный вывод:

result: 1777607782 69f42466
result: 2147483548 7fffff9c

если непонятно что делает foo() - делает число из строки, уникальное для данного набора и короче по длине и более дешевое в обработке. В итоге человеку проще писать, а компутеру проще читать. https://ru.wikipedia.org/wiki/Хеширование

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

Чё ты мне стандартом в морду тычешь? У прадедов работало, у дедов работало, у меня всё работало, пока какой-то моржовый хер стандарт не почитал и не сломал всё.

slapin ★★★★★
() автор топика

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

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

дык а в чем там может быть проблема? Почему оно решает забить приложить & 0x7fffffff? И почему они решили вдруг сломать устоявшееся поведение? Типа знаковый сдвиг, ага, могу поистерить и рандомно погадить... Но прикол в том что поведение самого сдвига не изменилось, оно дальше решило нагадить...

slapin ★★★★★
() автор топика
Ответ на: комментарий от Deleted

У него там целочисленное переполнение еще.

anonymous
()
Ответ на: комментарий от slapin
$ clang -O2 -Wall -Wextra -fsanitize=undefined ub.c -o ub
ub.c:7:50: warning: '^' within '|' [-Wbitwise-op-parentheses]
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                                            ~ ~~~^~~
ub.c:7:50: note: place parentheses around the '^' expression to silence this warning
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                                                 ^
                                              (     )
ub.c:7:59: warning: '^' within '|' [-Wbitwise-op-parentheses]
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                                                     ~ ~~~^~~
ub.c:7:59: note: place parentheses around the '^' expression to silence this warning
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                                                          ^
                                                       (     )
2 warnings generated.
[~/repo]-[%] ./ub
ub.c:7:26: runtime error: signed integer overflow: 481340559 * 20891 cannot be represented in type 'int'
ub.c:7:19: runtime error: signed integer overflow: 1752892743 + 454394588 cannot be represented in type 'int'
result: 1777607782 69f42466
result: 2147483548 7fffff9c

Знаковое переполнение — UB. Чини свой код.

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

И что, это влияет на & 0x7fffffff которое вообще убирает знак? И кстати шланг это правильно компилирует. То есть это скорее баг компилятора чем UB.

slapin ★★★★★
() автор топика
Ответ на: комментарий от shdown

Ну плевать мне в этом месте на целочисленное переполнение. Пущай переполняется. Отсебятину зачем гнать? Что потом будет? Будем sin(x) = 2 возвращать или sqrt отридцательный, если где-то рядом большое число не влезло в тип? Стандартное поведение - подрезать до типа, нечего мне мозги компостировать. А потом выполнить побитовую логическую операцию, а не болт на нее положить. UB не дает права гнать отсебятину или случайные числа генерить вместо ответов. Еще биткойны начните там майнить, типа раз UB значит можно... :(

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

Ты не знаешь, что такое UB, и пишешь чушь.

Отсебятину зачем гнать?

Потому что это UB.

Что потом будет?

Что угодно.

Стандартное поведение - подрезать до типа

Нет, стандарт говорит, что это UB.

UB не дает права гнать отсебятину или случайные числа генерить вместо ответов

Даёт.

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

если с -O2 работает, буду глядеть патчи

slapin ★★★★★
() автор топика
Ответ на: комментарий от anonymous
result: 1777607782 69f42466
result: 2147483548 7fffff9c

точно такой же выхлоп у шланга

clang version 6.0.1 (tags/RELEASE_601/final)

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

шланг с этим кодом работает, речь тут про gcc,

slapin ★★★★★
() автор топика
Ответ на: комментарий от slapin
set -x; for i in {0..3}; do gcc test.c -O$i -o test && ./test; done
+ for i in {0..3}
+ gcc test.c -O0 -o test
+ ./test
result: 1777607782 69f42466
result: 2147483548 7fffff9c
+ for i in {0..3}
+ gcc test.c -O1 -o test
+ ./test
result: 1777607782 69f42466
result: 2147483548 7fffff9c
+ for i in {0..3}
+ gcc test.c -O2 -o test
+ ./test
result: 1777607782 69f42466
result: 2147483548 7fffff9c
+ for i in {0..3}
+ gcc test.c -O3 -o test
+ ./test
result: 1777607782 69f42466
result: 2147483548 7fffff9c

Точно такой же выхлоп с clang 6.0.1

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

Ох лол, ты вообще не в курсе как это работает

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

Проблема в том что у GCC под ARM по непонятным для меня причинам сhar - без знаковый (0-255). Соотвецтвенно в цикле к цулому r всегда плюсуется положительное число. Компилятор сщитает что результатом работы цикла не может быть отрицательное значение в r (кроме как через переполнение которое UB). А следовательно последняя команда (r & 0x7fffffff) - лишняя так как никогда (кроме UB на которое пофиг) не меняет результат.

Вот он ее и выкинул, я - бы для портабельности кода сделал так:

int foo(const char *_s)
{
        unsigned int r = 0;
        unsigned char *s = (unsigned char*)(_s);
        while(*s) {
                r += ((r * 20891 + *s *200) | *s ^ 4 | *s ^ 3 ) ^ (r >> 1);
                s++;
        }
        return r & 0x7fffffff;
}

zaz ★★★★
()

А я-то думаю, где скотинко, а вон оно как.

anonymous
()

Например сброс знака по (a & 0x7fffffff) не работает

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

много всего вообще теперь не работает

довольно распространенное явление

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

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

не признаёт себя говнокодером

Оч странно это всё.

anonymous
()

Какой сейчас более-менее адекватный gcc, 5.4?

Только 2.95

buddhist ★★★★★
()

сброс знака

#include <stdlib.h>

int main(void)
{
   int a = -42;
   a = abs(a);
   return a;
}

gcc test.c
./a.out
echo $?
42

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