modelica-3rdparty/Modelica_DeviceDrivers

CLOCK_MONOTONIC not available in -std=c89

maltelenz opened this issue · 7 comments

Here, CLOCK_MONOTONIC is used:

int ret = clock_gettime(CLOCK_MONOTONIC, &rtSync->t_start);

This https://stackoverflow.com/a/8881705 says this is not available with the "proper" c standard version flags, and I indeed cannot compile the model in a tool which uses -std=c89:

Modelica_DeviceDrivers/Resources/Include/MDDRealtimeSynchronize.h:637:33: error: ‘CLOCK_MONOTONIC’ undeclared (first use in this function)
  637 |         int ret = clock_gettime(CLOCK_MONOTONIC, &rtSync->t_start);
      |                                 ^~~~~~~~~~~~~~~

Am I missing something, or is the library wrong?

Hm, for me this works in Dymola (openSUSE 15.4), even if I specify "-std=c89" in the compiler options. (At least after I remove a few comments in MDDRealtimeSynchronize starting with // which are not accepted with -std=c89.)

What tool and which OS are you using?

This was in a development version of System Modeler, and I see it across many platforms and compilers (Windows VS 2022, Linux GCC 8.5.0, Linux GCC 13.2, macOS Clang).

I can reproduce it stand-alone. This gives the error mentioned in my first message:

g++ -x c -std=c89 -m64 -fPIC -c Modelica_DeviceDrivers/Resources/Include/MDDRealtimeSynchronize.h

While if I change to -std=gnu89 it compiles:

g++ -x c -std=gnu89 -m64 -fPIC -c Modelica_DeviceDrivers/Resources/Include/MDDRealtimeSynchronize.h

Thanks, I can replicate this. If we add #define _POSIX_C_SOURCE 199309L as proposed in your linked stackoverflow discussion, it compiles.

MDD assumes that it can directly call Windows system calls or Linux/POSIX system call (macOS is not supported).

I'm not sure how harmful it is if I simply add the ``#define _POSIX_C_SOURCE 199309L` line to the code, like

#elif defined(__linux__)

#define _POSIX_C_SOURCE 199309L

Would that solve the issue for you?

I would expect that you get a different error with VS 2022, since it #ifdefs to a different code?

Would that solve the issue for you?

I can confirm that it compiles stand-alone in this case, and it seems like a reasonable solution.

It doesn't solve the issue completely in System Modeler, but that is because of a tool issue, which we will work on.

I would expect that you get a different error with VS 2022, since it #ifdefs to a different code?

Yes, apologies, that is a completely different issue, which I'll have to dig into a bit more. If it turns out to be a problem with the library, I'll open a separate issue.

Edit: Oh, and there are a few // style comments in the same file, which are also not valid, which I had to remove to make it compile.

Okay, should be fixed now.

@maltelenz Realized that my first "fix" introduces new problems, e.g.,

g++ -x c -std=gnu99 -m64 -fPIC -c Modelica_DeviceDrivers/Resources/Include/MDDRealtimeSynchronize.h

won't compile with #define _POSIX_C_SOURCE 199309L. After experimenting with gcc and clang I introduced some conditionals in 0f40a7b:

#if !defined(linux) && !defined(unix) && !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 199309L
#endif

It is guess work, but I hope it is robust enough for most practical use cases. I'm open for better proposals...

Realized that my first "fix" introduces new problems, e.g.,

g++ -x c -std=gnu99 -m64 -fPIC -c Modelica_DeviceDrivers/Resources/Include/MDDRealtimeSynchronize.h

won't compile with #define _POSIX_C_SOURCE 199309L.

I guess that should technically not happen in a strict Modelica environment, since the Modelica standard specifies C89...

After experimenting with gcc and clang I introduced some conditionals in 0f40a7b:

This still seems to work for me in the development version of System Modeler.