Ближнее и дальнее несоответствие

Я перешел и рефакторинг некоторого кода. Я закончил тем, что изменил функцию из:

void setPerspective(float nearP = 0.1f, float farP = 1000.0f);

в

void setPerspective(float near = 0.1f, float far = 1000.0f);

и начал получать много странного 'missing ;' а также 'missing )' ошибки.

Кажется, что near а также far являются #defineд в windef.h, Справедливо; Я буду избегать их использования.

Но потом я заметил в другом заголовочном файле:

void setPerspective(float fov, float aspect, float near, float far);

Все же я не получаю проблем. Оба этих заголовочных файла имеют одинаковые #includes …

Есть идеи, почему я получаю проблемы в одном, а не в другом? Кажется, это не параметры по умолчанию. Это какой-то произвольный порядок #includeМожет ли это вызывать проблемы с одним заголовочным файлом, а не с другим?

5

Решение

Жетоны near а также far вероятно определены как пустые в пустом #define как это

#define near
#define far

поэтому препроцессор заменит их на null — они исчезнут до того, как компилятор обработает исходный код.

Первое объявление функции включает в себя присвоение параметров по умолчанию

void setPerspective(float nearP = 0.1f, float farP = 1000.0f);

Компилятор правильно интерпретирует nearP и farP как имя параметра и float как тип. Когда вы меняете nearP в near а также farP в far препроцессор заменяет их на ноль, и у вас есть назначение float тип … и компилятор подбрасывает … вот что видит компилятор:

void setPerspective(float  = 0.1f, float  = 1000.0f);

Во втором заголовочном файле параметры в прототипе функции не имеют назначения по умолчанию, а компилятор видит параметры с плавающей точкой и не видит near а также far потому что они нулевые … так что вместо этого

void setPerspective(float fov, float aspect, float near, float far);

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

void setPerspective(float fov, float aspect, float , float );

это совершенно законный прототип функции (вам не нужно давать имена параметров).

7

Другие решения

По-видимому, вы компилируете на машине с Windows.

Когда-то давным-давно, затерявшись в глубине веков, были такие машины, как Intel 8086, 80186 и 80286. На этих машинах у вас была ограниченная доступная память. В основном они использовали 16-битные указатели. Но затем программы немного выросли, поэтому ключевые слова near а также far были добавлены в качестве классификаторов для определения различных размеров указателя.

То, с чем вы сталкиваетесь, — это пережиток тех мрачных исконных дней. Нормальные компьютеры (начиная с 80386) не нуждались в near а также far нотации, но компиляторы продолжали поддерживать их для обратной совместимости.

Если этот диагноз точный, избегайте использования имен near а также far; трактуйте их как ключевые слова, оставшиеся от старой версии языка.

4

Посмотрите на этот пост: Ближний и дальний указатели

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

Похоже, что для них были причины называться nearP и farP. 🙂

2

На заголовочные файлы влияют не только их собственные #includeс, но и по #includes, которые встречаются в корневом исходном файле до этих заголовков.

/* foo.cpp */
#include "bar.h"#include "foo.h" // foo.h is influenced by whatever is brought in by bar.h

Идентификаторы far а также near (также как и другие) — это расширения, найденные в некоторых компиляторах, предназначенных для сегментированной архитектуры 8086/88 (на которой работали MS-DOS и Windows 3.x). В заголовочных файлах Windows может быть что-то для поддержки устаревшего кода, например, может быть #define far (определите это ни к чему).

С другой стороны, вы должны обычно использовать double для чисел с плавающей точкой.
float тип для сохранения памяти в больших массивах (может быть или не быть меньше, чем double). На платформах, которые имеют числа с плавающей точкой IEEE 754, float обычно это 32-битное число: оно имеет 7-битную экспоненту и 24-битную мантиссу, что довольно плохо. В то время как double это 64-битный тип, с 11-битной экспонентой и 52-битной мантиссой: существенно лучший диапазон и точность.

2