LINUX.ORG.RU

Как это можно было сломать, в компиляторе С

 


0

2
#define C0(U,r,blur) smoothstep(r, r - blur, length(U) )

float C1(vec2 U, float r, float blur)
    {return C0(U,r,blur);}

макрос C0 и функция C1 дают разный результат при вызове, как это возможно?

результат разный в том что одна(C1) дажет 0(нель) там где другая(C1) дает 1(еденицу)

пример вызова

C1( U, .03 * 5., .003 * 5.); //тут 0
C0( U, .03 * 5., .003 * 5.); //тут 1

это нвидия-компилятор-C

убедиться можно тут(работает только в линуксе, из браузера) https://www.shadertoy.com/view/WdX3zX

как можно было так написать компилятор, чтоб он так делал, кто знает?

Deleted

Меня терзают смутные сомнения

что язык для шейдеров — это нифига не C.

anonymous
()

.03 * 5. .003 * 5.

Это всё литералы типа double, а функция C1 принимает float. В этом может быть и разница.

xaizek ★★★★★
()
Ответ на: Меня терзают смутные сомнения от anonymous

что язык для шейдеров — это нифига не C.

в примере, оба значения «прекомпилируются» компилятором на CPU, и готовый скомпилированный бинарник содержит готовые значения, GPU тут не использутся вообще никак

Deleted
()

Сломан тут только твой код.

https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/smoothstep.xhtml

Results are undefined if edge0 ≥ edge1.

как можно было так написать компилятор, чтоб он так делал, кто знает?

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

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

Это всё литералы типа double, а функция C1 принимает float. В этом может быть и разница.

да, это может бывает проблемой, но не в этом случае

вот идентичный код на Си для gcc https://rextester.com/MWR3049 (передавая флоат или доубле не имеют значение)

тут именно разница в вызове макроса и функции(которая вызывает тотже макрос)

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

Results are undefined if edge0 ≥ edge1.

и он(результат) должен быть «идентичен» везде

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

да это так

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

и он(результат) должен быть «идентичен» везде

В Си — точно нет. Про GLSL не скажу.

NeXTSTEP ★★
()

как можно было так написать компилятор, чтоб он так делал, кто знает?

Знают индусы которые клепают проприетарщину для невидии за миску риса

anonymous
()

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

neon1ks ★★
()

Аргументы у C1 сделай double и посмотри, что получится.

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

это нвидия-компилятор-C

А это клоун с лора.

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

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

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

Научитесь в начале макросами пользоваться. Всё здесь правильно работает:

#define bar(a,b) ((int)((a + 10) > (b)))

int foo(int a, int b) {
	return a + 10 > b;
}
neon1ks ★★
()
Ответ на: комментарий от anonymous

О, я не посмотрел пример по ссылке. Здесь переполнение диапазона переменной, а для знаковой целочисленной переменной — это undefined behaviour.

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

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

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

Здесь переполнение диапазона переменной, а для знаковой целочисленной переменной — это undefined behaviour.

👍

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

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


gcc -Wall -std=c17 -O3 -o "macros" "macros.c" (в каталоге: /home/maksim/Desktop/test2)
macros.c: In function ‘main’:
macros.c:5:19: warning: iteration 9 invokes undefined behavior (-Waggressive-loop-optimizations)
     return a + 10 > b;
            ~~~~~~~^~~
macros.c:11:5: note: within this loop
     for (int i = 2147483630; i < 2147483647; i++)
     ^~~
Сборка прошла успешно.

[\code]
neon1ks ★★
()
Ответ на: комментарий от slovazap

понятие вполне конкретное и ограниченное стандартом

И какой же стандарт нужно учить? Или нужно учить все? А что делать с компиляторами, у которых своя специфика?

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

И какой же стандарт нужно учить? Или нужно учить все?

Стандарт того языка на котором пишете. «Все» один единственный.

А что делать с компиляторами, у которых своя специфика?

Какая ещё специфика? Стандарт либо соблюдается и тогда достаточно его почитать, либо не соблюдается, и тогда не надо использовать такой компилятор.

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

Каким стандартом ограничен язык, на котором написано ядро Linux?

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

Ламеры это те, кто пишет криво говнокод с UB, тут и шавбодные компиляторы не помогут.

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

Спасибо, я обязательно посмотрю. Оказалось, что intel подложил мину, у него ffast-math идёт по умолчанию. Это самое неприятное, вместо того, чтобы свою числодробилку в порядок приводить, я вынужден выяснять, что эти умники там наворотили.

ZERG ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.