I've been going over and refactoring some code. I ended up changing a function from:
void setPerspective(float nearP = 0.1f, float farP = 1000.0f);
to
void setPerspective(float near = 0.1f, float far = 1000.0f);
and started getting a lot of strange 'missing ;'
and 'missing )'
errors.
It seems that near
and far
are #define
d in windef.h
. Fair enough; I'll avoid using them.
But then I noticed in another header file:
void setPerspective(float fov, float aspect, float near, float far);
Yet I get no trouble. Both of these header files have the same #include
s...
Any idea why I'm getting issues in one, but not another? It doesn't seem to be the default parameters. Is it some arbitrary ordering of the #include
s that might be causing issues with one header file and not another?
The tokens near
and far
are probably defined to be null in an empty #define
like this
#define near
#define far
so the pre-processor will replace them with null - they disappear prior to the compiler processing the source.
The first function declaration includes the default assignment to the parameters
void setPerspective(float nearP = 0.1f, float farP = 1000.0f);
The compiler correctly interprets nearP and farP as the parameter name and float
as the type. When you change nearP
to near
and farP
to far
the pre-processor replaces them with null and you have an assignment to the float
type... and the compiler throws a fit... this is what the compiler sees:
void setPerspective(float = 0.1f, float = 1000.0f);
In the second header file the parameters in the function prototype don't have default assignment, and the compiler sees the parameters are float and doesn't see near
and far
because they are null... so instead of this
void setPerspective(float fov, float aspect, float near, float far);
the compiler sees this
void setPerspective(float fov, float aspect, float , float );
which is a perfectly legal function prototype (you don't have to give the parameters names).
At a guess, you are compiling on a Windows machine.
Once upon a long time ago, lost in the mists of time, there were machines like the Intel 8086, 80186, and 80286. On these machines, you had limited memory available. They mostly used 16-bit pointers. But then programs grew a bit, so the keywords near
and far
were added as qualifiers to identify different sizes of pointer.
What you're running into is a leftover from those dark primordial days. Sane computers (80386 onwards) didn't need the near
and far
notation, but the compilers continued to support them for backwards compatibility.
If this diagnosis is accurate, avoid using the names near
and far
; treat them as keywords leftover from an old version of the language.
Look at this post: Near and Far pointers
They seem to have been types of pointers for accessing different types of memory but aren't used anymore.
Looks like there was a reason for them being called nearP and farP. :)
Header files are influenced not only by their own #include
s but also by the #include
s which occur in the root source file prior to those headers.
/* foo.cpp */
#include "bar.h"
#include "foo.h" // foo.h is influenced by whatever is brought in by bar.h
The identifiers far
and near
(as well as others) are extensions found in some compilers targetting the 8086/88 segmented architecture (on which ran MS-DOS and Windows 3.x). There could be something in the Windows header files for supporting legacy code, like maybe #define far
(define it to nothing).
On a different note, you should usually be using double
for floating point numbers.
The float
type is for saving storage in large arrays (it may or may not be smaller than double
). On platforms that have IEEE 754 floating point numbers, float
is usually a 32 bit number: it has a 7 bit exponsent and 24 bit mantissa, which is quite poor. Whereas double
is a 64 bit type, with an 11 bit exponent and a 52 bit mantissa: substantially better range and precision.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With