近乎不一致

时间:2012-09-23 22:34:08

标签: c++ windows variables tags c-preprocessor

我一直在重复并重构一些代码。我最终改变了一个函数:

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

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

并开始收到很多奇怪的'missing ;''missing )'错误。

near中似乎far#definewindef.h d。很公平;我会避免使用它们。

但后来我注意到另一个头文件:

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

但我没有遇到麻烦。这两个头文件都具有相同的#include s ...

我知道为什么我会在一个问题中找到问题,而不是另一个问题?它似乎不是默认参数。是#include的一些任意排序可能导致一个头文件而不是另一个头文件出现问题?

4 个答案:

答案 0 :(得分:7)

令牌nearfar可能在空#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,并且看不到nearfar,因为它们是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位指针。但随后程序增长了一些,因此关键字nearfar被添加为限定符以识别不同大小的指针。

你遇到的是那些黑暗原始日子的遗留物。 Sane计算机(80386以后)不需要nearfar表示法,但编译器继续支持它们以便向后兼容。

如果此诊断准确无误,请避免使用名称nearfar;从旧版本的语言中将它们视为剩余的关键词。

答案 2 :(得分:2)

看看这篇文章:Near and Far pointers

它们似乎是用于访问不同类型内存但不再使用的指针类型。

看起来有理由将它们称为nearP和farP。 :)

答案 3 :(得分:2)

头文件不仅会受到他们自己的#include的影响,还会受到这些头文件之前根源文件中出现的#include的影响。

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

标识符farnear(以及其他标识符)是在一些编译器中找到的扩展,这些编译器针对8086/88分段体系结构(运行MS-DOS和Windows 3.x)。 Windows头文件中可能存在用于支持遗留代码的内容,例如#define far(将其定义为空)。

另一方面,您通常应该使用double作为浮点数。 float类型用于在大型数组中保存存储(它可能小于或等于double)。在具有IEEE 754浮点数的平台上,float通常是32位数:它具有7位指数和24位尾数,这是非常差的。 double是64位类型,11位指数和52位尾数:明显更好的范围和精度。