1

I have a codebase in C99 that compiles and runs perfectly on Linux with both GCC and Clang; however, on MinGW-w64 (installed through MSYS2), it gives errors like

include/math3d.h: In function 'matPerspective':
include/math3d.h:577:1: error: parameter name omitted
matPerspective (float y_fov, float aspect, float near, float far)
 ^~~~~~~~~~~~~~
include/math3d.h:577:1: error: parameter name omitted
include/math3d.h:595:28: error: expected expression before ')' token
  m.elem[10] = -((far + near) / (far - near));
                        ^
include/math3d.h:600:34: error: expected expression before ')' token
  m.elem[14] = -((2.0 * far * near) / (far - near));

As evident, it can't even parse the header file without puking all over itself. The part of program with errors is:

static inline Matrix
matPerspective (float y_fov, float aspect, float near, float far)
{
    float a = 1.0/tan(y_fov/2.0);

    Matrix m;

    m.elem[0] = a / aspect;
    m.elem[1] = 0.0;
    m.elem[2] = 0.0;
    m.elem[3] = 0.0;

    m.elem[4] = 0.0;
    m.elem[5] = a;
    m.elem[6] = 0.0;
    m.elem[7] = 0.0;

    m.elem[8] = 0.0;
    m.elem[9] = 0.0;
    m.elem[10] = -((far + near) / (far - near));
    m.elem[11] = -1.0;

    m.elem[12] = 0.0;
    m.elem[13] = 0.0;
    m.elem[14] = -((2.0 * far * near) / (far - near));
    m.elem[15] = 0.0;

    return m;
}

I have been using this same code for over a month on Linux and everything works perfectly there.

The command used to compile was:

gcc -c -o obj/win/x86_64/code.o src/code.c -Iinclude -std=c99

The operating system used is Window 7 x64. Compiler was installed through MSYS2 by installing package group mingw-w64-x86_64-toolchain. The compilation was done (or atleast tried) on the MinGW64 shell created by MSYS2 upon installation.

Paul R
  • 208,748
  • 37
  • 389
  • 560
strNOcat
  • 913
  • 2
  • 8
  • 22

1 Answers1

4

It looks like the problem is the use of far and near as parameter names - these were keywords which historically had a special meaning on crusty old x86 compilers when compiling code for segmented (16 bit) architectures - try changing the names of these parameters, to e.g. far_val and near_val.

Addition by OP: The problem was that GLAD loader includes WinDef.h which defines

#define far 

and

#define near

essentially messing up the syntax.

strNOcat
  • 913
  • 2
  • 8
  • 22
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    Wow, I love Microsoft. Any list of additional keywords they have added to C? And why on earth is it carrying DOS baggage? Win7 doesn't even run DOS programs – strNOcat Sep 15 '16 at 09:05
  • I feel your pain - I write cross-platform C/C++ code and it's always the Windows builds that cause the most problems and require the most "dumbing down" of the code. – Paul R Sep 15 '16 at 09:43
  • Oh and I think `huge` might also be a similar anachronistic keyword that you might want to avoid. – Paul R Sep 15 '16 at 09:51
  • Not sure why you're blaming Microsoft when you're using GCC! Your code compiles perfectly well in Visual Studio ... – Harry Johnston Sep 15 '16 at 22:26
  • 1
    @HarryJohnston What are you talking about? https://stackoverflow.com/questions/8948493/visual-studio-doesnt-allow-me-to-use-certain-variable-names Infact, it is WinDef.h that is causing this problem; so yes, I blame Microsoft. – strNOcat Sep 16 '16 at 00:18
  • 1
    Also relevant: https://stackoverflow.com/questions/34932012/cant-name-variables-far-and-near-when-using-glad?rq=1 – strNOcat Sep 16 '16 at 00:18
  • 1
    @NamanDixit: that's a different issue, I believe, which is only a problem *if you include the windows headers*. Nothing to do with the compiler itself. Since your code runs on Linux, I assume it isn't including the Windows headers, so the problem in this case is presumably GCC. – Harry Johnston Sep 16 '16 at 00:29
  • 1
    @HarryJohnston No, my codebase would NOT have compiled on VS either, because the problem is in WinDef.h which is provided by Microsoft and breaks cross-platform compatibility. GCC simply used the header provided by Microsoft (available here: https://www.cygwin.com/ml/cygwin/2003-06/msg00470/windef.h). The WinDef.h is only included on Windows by a #ifdef – strNOcat Sep 16 '16 at 00:37
  • 1
    @NamanDixit: well, there's your problem then. You're not supposed to include that header in cross-platform code. Complaining that including the Win32 API headers breaks the language standard by reserving "near" and "far" is like complaining that including the POSIX headers breaks the language standard by reserving "open" and "close"! – Harry Johnston Sep 16 '16 at 00:46
  • 1
    @HarryJohnston The point was that they shouldn't had included DOS cruft in newer OS, but that's not for any of us to fix - so no point bemoaning it. – strNOcat Sep 16 '16 at 00:51
  • 1
    @NamanDixit: I don't know, I think there's probably a surprising amount of Windows code out there (originally written for 16-bit Windows) which still depends on that particular backwards-compatibility hack. And, after all, it's only two or three extra reserved names. But I agree that there's little point in debating it, it is what it is. (You may still want to consider separating out your cross-platform code from your OS-specific code, though, to avoid similar problems in future.) – Harry Johnston Sep 16 '16 at 01:02
  • @NamanDixit DOS programs still run perfectly well on Windows 7. As do 16-bit Windows applications, which still use `near` and `far`. The only break is on 64-bit Windows, since x86-64 no longer supports 16-bit code. Just because you're used to an environment that breaks compatibility with minor patches doesn't mean that all platforms do that :) – Luaan Sep 16 '16 at 07:02
  • You always have the most trouble with Windows builds, and Windows programmers have the most trouble with non-Windows builds. I wonder if there's some similarity... – Luaan Sep 16 '16 at 07:04
  • @Luaan: the main problem for Windows programmers is that Visual C++ is very lax in what it compiles, so they end up writing sloppy invalid code which happens to compile on Windows but then needs to be fixed when they try to compile it on a proper OS with a decent compiler. – Paul R Sep 16 '16 at 07:23
  • Yeah, that's definitely a problem. The default configuration of the compiler is less than optimal, and setting it up properly is not entirely trivial. That said, I've had the same kind of trouble with GCC in the past. But in my experience, by far the most issues with cross-platform code is that the guy writing it still thinks platform-specific without realizing it. And of course, the vastly different toolsets and *mindsets* between development on Linuxy-systems and Windows. C++ is rarely my first language of choice in part because of annoyances like this :) – Luaan Sep 16 '16 at 07:34
  • @Luaan: yes, but unfortunately it tends to be the Windows programmers who write platform-specific code (since they usually only have Windows experience and see everything through Microsoft-coloured glasses). I write cross-platform code for several different OS's and several compilers and the most common annoyance is having to fix the code that the Windows guys check in, either because it's not valid C/C++ or because they have used something non-standard and Microsoft-specific. There are numerous other major problems with cross-platform code on Windows too, but this is the worst. – Paul R Sep 16 '16 at 07:40
  • Yup, no argument there. I have when people think that cross-platform development is easy - it usually means they don't even realize how many assumptions based on their preferred platform they are making :) A lot of code written for Linux (and friends) is still meant to run on Windows simply because there's so many Windows systems around; the reverse still isn't true, though it's getting better over time. And truth be told, I'm far more interested in things like proper internationalization and such than supporting Linux, since the return on investment is so much bigger. – Luaan Sep 16 '16 at 08:10
  • Indeed - there can be quite subtle problems, even when just switching between different compilers on the same platform. One bonus of making your code compile and run with multiple compilers on multiple platforms though is that you tend to flush out latent bugs that might not otherwise have been noticed (until much later perhaps) in a single platform context. – Paul R Sep 16 '16 at 08:13