我一直在重复并重构一些代码。我最终改变了一个函数:
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
d。很公平;我会避免使用它们。
但后来我注意到另一个头文件:
void setPerspective(float fov, float aspect, float near, float far);
但我没有遇到麻烦。这两个头文件都具有相同的#include
s ...
我知道为什么我会在一个问题中找到问题,而不是另一个问题?它似乎不是默认参数。是#include
的一些任意排序可能导致一个头文件而不是另一个头文件出现问题?
答案 0 :(得分:7)
令牌near
和far
可能在空#define
中被定义为null
#define near
#define far
因此预处理器将用null替换它们 - 它们在编译器处理源之前消失。
第一个函数声明包括参数的默认赋值
void setPerspective(float nearP = 0.1f, float farP = 1000.0f);
编译器正确地将nearP和farP解释为参数名称,并将float
解释为类型。当您将nearP
更改为near
并将farP
更改为far
时,预处理程序会将其替换为null,并且您对float
类型进行了分配...并且编译器抛出一个拟合...这是编译器看到的:
void setPerspective(float = 0.1f, float = 1000.0f);
在第二个头文件中,函数原型中的参数没有默认赋值,编译器看到参数是float,并且看不到near
和far
,因为它们是null。 ..所以而不是这个
void setPerspective(float fov, float aspect, float near, float far);
编译器看到了这个
void setPerspective(float fov, float aspect, float , float );
这是一个完全合法的函数原型(您不必提供参数名称)。
答案 1 :(得分:4)
猜测,您正在Windows机器上进行编译。
很久以前,迷失在时间的迷雾中,有像英特尔8086,80186和80286这样的机器。在这些机器上,你的内存有限。他们大多使用16位指针。但随后程序增长了一些,因此关键字near
和far
被添加为限定符以识别不同大小的指针。
你遇到的是那些黑暗原始日子的遗留物。 Sane计算机(80386以后)不需要near
和far
表示法,但编译器继续支持它们以便向后兼容。
如果此诊断准确无误,请避免使用名称near
和far
;从旧版本的语言中将它们视为剩余的关键词。
答案 2 :(得分:2)
答案 3 :(得分:2)
头文件不仅会受到他们自己的#include
的影响,还会受到这些头文件之前根源文件中出现的#include
的影响。
/* 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位尾数:明显更好的范围和精度。