Я перешел и рефакторинг некоторого кода. Я закончил тем, что изменил функцию из:
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);
Все же я не получаю проблем. Оба этих заголовочных файла имеют одинаковые #include
s …
Есть идеи, почему я получаю проблемы в одном, а не в другом? Кажется, это не параметры по умолчанию. Это какой-то произвольный порядок #include
Может ли это вызывать проблемы с одним заголовочным файлом, а не с другим?
Жетоны 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 );
это совершенно законный прототип функции (вам не нужно давать имена параметров).
По-видимому, вы компилируете на машине с Windows.
Когда-то давным-давно, затерявшись в глубине веков, были такие машины, как Intel 8086, 80186 и 80286. На этих машинах у вас была ограниченная доступная память. В основном они использовали 16-битные указатели. Но затем программы немного выросли, поэтому ключевые слова near
а также far
были добавлены в качестве классификаторов для определения различных размеров указателя.
То, с чем вы сталкиваетесь, — это пережиток тех мрачных исконных дней. Нормальные компьютеры (начиная с 80386) не нуждались в near
а также far
нотации, но компиляторы продолжали поддерживать их для обратной совместимости.
Если этот диагноз точный, избегайте использования имен near
а также far
; трактуйте их как ключевые слова, оставшиеся от старой версии языка.
Посмотрите на этот пост: Ближний и дальний указатели
Похоже, они были типами указателей для доступа к различным типам памяти, но больше не используются.
Похоже, что для них были причины называться nearP и farP. 🙂
На заголовочные файлы влияют не только их собственные #include
с, но и по #include
s, которые встречаются в корневом исходном файле до этих заголовков.
/* 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-битной мантиссой: существенно лучший диапазон и точность.