Мне сказали, что C и C++ имеют «неопределенное поведение», то есть один и тот же код может вести себя по-разному на разных платформах или при использовании разных компиляторов, если я использую «определенные конструкции».
Это не то, что на самом деле означает неопределенное поведение. Это результат неопределенного поведения, но оно не для этого.
Спецификации — это определение того, что происходит, когда вы что-то делаете. Он говорит, какие значения параметров хорошие, а какие плохие. Если вы пропускаете плохие, он сообщает вам, какие ошибки вы получаете и в каком состоянии будет система. Если текущее состояние недопустимо для операции, которую вы пытаетесь выполнить, в спецификации объясняется, какие другие типы ошибок вы получаете и что это означает для состояния системы впоследствии.
Когда вы используете определенное поведение, вы полагаетесь на контракт между вами и реализацией; этот контракт называется спецификацией OpenGL. Вы полагаетесь на реализацию, чтобы обеспечить проверки достоверности, требуемые спецификацией. И вы полагаетесь на то, что реализация делает то, что говорит спецификация. Если реализация не реализует что-то правильно, то она нарушает контракт.
Когда в спецификации говорится, что определенный набор вещей приведет к "неопределенному поведению", это означает, что выполнение этих действий означает, что вы нарушаете контракт. Вы находитесь за краем карты. Вы делаете что-то, для чего спецификация не обеспечивает определенного поведения; ты нарушил свою часть сделки.
Иными словами, ваш код будет полностью переносимым, пока вы не полагаетесь на неопределенное поведение. Вот что это значит.
Как правило, спецификация помечает что-то неопределенное, если его тестирование было бы обременительным бременем для реализаций. В конце концов, OpenGL должен быть достаточно быстрым. Таким образом, они стараются избегать обременения драйвера, заставляя его проверять вещи, которые почти невозможно проверить.
Кроме того, есть тесты, которые невозможно протестировать. В OpenGL запрещено читать и записывать одно и то же изображение, связывая изображение как текстуру и производя выборку из него, одновременно присоединяя это изображение к FBO и выполняя рендеринг в него. Не существует способа гарантированно протестировать этот сценарий.
О, вы можете протестировать большую часть этого. Вы можете потерпеть неудачу при вызовах отрисовки, когда одна и та же текстура привязана к FBO и к сэмплеру. Но тогда вы не сможете рендерить одну и ту же текстуру в разные MIP-карты; помните: каждый мипмап — это отдельное изображение. Таким образом, вы можете проверить, допускает ли диапазон базового/максимального уровня возможность выборки из MIP-карты, привязанной к FBO. Но это ложится тяжелым бременем на пользователя, так как ему придется постоянно настраивать базовый/максимальный уровень при рендеринге в разные MIP-карты. Им гораздо проще просто взять образец из правильного MIP-карты с textureLOD
или подобными функциями. И вы не можете определить до времени выполнения, делают ли они выборку из-за пределов этого уровня MIP-карты.
OpenCL и OpenGL SL имеют неопределенное поведение, как и многие спецификации. И, как правило, он не определен по тем же причинам: его тестирование сделало бы реализацию неприемлемо медленнее или тестирование было бы совершенно невозможным.
person
Nicol Bolas
schedule
17.09.2011