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 ★★★★★ ()
Ответ на: комментарий от 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 ★★★★★ ()
Ответ на: комментарий от anonymous

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

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

result: 1777607782 69f42466
result: 2147483548 7fffff9c

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

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

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

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

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

slapin ★★★★★ ()
Ответ на: комментарий от 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

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

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

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

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

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

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

Что угодно.

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

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

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

Даёт.

shdown ()
Ответ на: комментарий от 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

Проблема в том что у 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 ★★★★ ()

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

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

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

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

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

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

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

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

anonymous ()