特殊错误 - 参数尚不存在,直到参数名称更改然后它更有利地中断

peculiar bug - parameter doesn't exist yet builds, until name of parameter changes then it breaks more favourably

注:f32是浮点数,m4x4是线性4乘4矩阵。 我有一个功能: inline m4x4 Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 nearr, f32 far)

您可能会注意到它有一个拼写错误。这是因为如果我调用参数 'near' 代码不会编译。当我将它更改为 nearr 并编译时,情况变得更糟,因为 far 不再存在。不在调试器中,不在反汇编中,名称就消失了,代码的行为也中断了。例如。我对近处使用值 -1,对远处使用 1,这具有翻转和反转我正在渲染的三角形的行为。当我将函数签名更改为以下内容时,代码按预期工作: inline m4x4 Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 nearplane, f32 farplane)

通过更改名称,代码神奇地没问题。我观察到的一件事是它似乎与字符 r 有关。

我更改了名称、调换了参数顺序、在调试器中单步执行、更改了函数体并查看了反汇编等。参数的顺序没有任何改变。尾随的 r 似乎很重要,但我不知道为什么,我很困惑。我的装配知识可能太薄弱了。下面是未经修改地复制和粘贴的代码,其中包含几天前我最后一次在电脑前试图弄明白时所做的评论。

    inline m4x4  // TODO go through the dissasembly 
inline m4x4 Orthographic(f32 left, f32 right, f32 nearr, f32 far, f32 bottom, f32 top)
    //NOTE this is also broken so its not just param order 
//Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 nearr, f32 far)
//Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far)
{ // TODO this is broken because far doesn't seem to exist???   if i change near to nearr then it compiles but far doesnt exist, if i set it as near then it fails to compile
    m4x4 Result;
    f32 dw = right - left;
    f32 dh = top - bottom; 
    //f32 dd = far - near;
    f32 dd = far - nearr;

    f32 width = right + left;
    f32 height = top + bottom;
    //f32 depth = far + near;
    f32 depth = far + nearr;

    Result = 
    {
        2/dw, 0.0f, 0.0f, -(width/dw),
        0.0f, 2/dh, 0.0f, -(height/dh),
        0.0f, 0.0f, -2/dd, -(depth/dd),
        0.0f, 0.0f, 0.0f, 1.0f,
    };

    return (Result);
}
#else
    inline m4x4
Orthographic(f32 left, f32 right, f32 bottom, f32 top, f32 nearplane, f32 farplane)
{ //TODO find out what the deal is with f32 near because this shit is crazy and it caused a painful bug
    m4x4 Result;
    f32 dw = right - left;
    f32 dh = top - bottom; 
    f32 dd = farplane - nearplane;

    f32 width = right + left;
    f32 height = top + bottom;
    f32 depth = farplane + nearplane;

    Result = 
    {
        2/dw, 0.0f, 0.0f, -(width/dw),
        0.0f, 2/dh, 0.0f, -(height/dh),
        0.0f, 0.0f,-2/dd, -(depth/dd),
        0.0f, 0.0f, 0.0f, 1.0f,
    };

    return (Result);
}



#endif 

我希望所有参数都应该显示在调试器中,并且它们的值应该出现在逻辑中...我还希望当额外的 r 添加到 ident 的名称时,它应该不会成功构建和 ​​运行,当然至少不在调试器中,但是...

当nearr去掉额外的r后编译失败,命令行输出如下。 maths.h(443): 错误 c2059: 语法错误: ';' maths.h(448):错误 c2059:语法错误:';'

我在搜索代码库时没有看到该错误的重要性。 443和448在函数体中,是far和nearr参数的行。

编辑:我的工作流程涉及在 vim 中工作并在命令行进行编译,我使用 visual studio 作为我的调试器。


使用以下代码示例充分观察问题


#include <stdio.h>
#include <windows.h>

#if 0 //change to 1 to fix
#undef near
#undef far
#endif 

float BrokenByMacro(float near, float far)
{
    float Result = near + far;

    return(Result);
}

int main()
{
    float MyFloat = BrokenByMacro(1, 2);
    printf("%f", MyFloat);
    return (0);
}

根据您使用的 MSVC 的错误格式判断,并且可能受到项目中某处 Windows headers 不卫生包含的影响(windef.hwindows.h 可能罪魁祸首)。

这些 headers 倾向于定义大量宏,这些宏经常以微妙的方式与用户代码发生冲突。在您的特定情况下,您似乎受到 farnear 宏的影响,这些宏通常会扩展为空。

如相关 SO question 中所建议,您只需将它们 #undef 放在适当的位置即可。尽管我也会考虑您的 #include 层次结构来限制 windows-specific headers' 范围。