mackron / miniaudio

Audio playback and capture library written in C, in a single source file.
https://miniaud.io
Other
4.07k stars 361 forks source link

Integer width compile-time errors when using undocumented MA_USE_STDINT option #673

Closed Spotlightsrule closed 1 year ago

Spotlightsrule commented 1 year ago

I was working with Miniaudio on a project and I noticed it had an undocumented option: MA_USE_STDINT. In short, it forces the custom ma_* integral types into their stdint.h equivalents. This was addressed in feature request #334. However, there seems to be an issue on LP64 platforms (ie: 64-bit Linux) that define uint64_t to be long unsigned int, which causes issues with interop between different components of the library (see below). The library is usable without this option, but it would be nice to be able to properly use the inbuilt fixed width types vs having to mix them in my code.

References: https://en.cppreference.com/w/cpp/language/types, https://en.cppreference.com/w/cpp/types/integer The error:

$ g++ miniaudio-loop.cpp -o miniaudio-loop && miniaudio-loop 
In file included from miniaudio-loop.cpp:6:
_lib/miniaudio/miniaudio.h: In function ‘ma_uint64 ma_atomic_uint64_compare_and_swap(ma_atomic_uint64*, ma_uint64, ma_uint64)’:
_lib/miniaudio/miniaudio.h:15929:73: error: invalid conversion from ‘ma_uint64*’ {aka ‘long unsigned int*’} to ‘volatile c89atomic_uint64*’ {aka ‘volatile long long unsigned int*’} [-fpermissive]
15929 |         return (ma_##type)c89atomic_compare_and_swap_##c89TypeExtension(&x->value, expected, desired); \
      |                                                                         ^~~~~~~~~
      |                                                                         |
      |                                                                         ma_uint64* {aka long unsigned int*}
_lib/miniaudio/miniaudio.h:15956:1: note: in expansion of macro ‘MA_ATOMIC_SAFE_TYPE_IMPL’
15956 | MA_ATOMIC_SAFE_TYPE_IMPL(64,  uint64)
      | ^~~~~~~~~~~~~~~~~~~~~~~~
_lib/miniaudio/miniaudio.h:14826:103: note:   initializing argument 1 of ‘c89atomic_uint64 c89atomic_compare_and_swap_64(volatile c89atomic_uint64*, c89atomic_uint64, c89atomic_uint64)’
14826 |     static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 desired)
      |                                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
_lib/miniaudio/miniaudio.h: In function ‘ma_bool32 ma_job_queue_cas(volatile ma_uint64*, ma_uint64, ma_uint64)’:
_lib/miniaudio/miniaudio.h:17627:42: error: invalid conversion from ‘volatile ma_uint64*’ {aka ‘volatile long unsigned int*’} to ‘volatile c89atomic_uint64*’ {aka ‘volatile long long unsigned int*’} [-fpermissive]
17627 |     return c89atomic_compare_and_swap_64(dst, expected, ma_job_set_refcount(desired, ma_job_extract_refcount(expected) + 1)) == expected;
      |                                          ^~~
      |                                          |
      |                                          volatile ma_uint64* {aka volatile long unsigned int*}
_lib/miniaudio/miniaudio.h:14826:103: note:   initializing argument 1 of ‘c89atomic_uint64 c89atomic_compare_and_swap_64(volatile c89atomic_uint64*, c89atomic_uint64, c89atomic_uint64)’
14826 |     static C89ATOMIC_INLINE c89atomic_uint64 c89atomic_compare_and_swap_64(volatile c89atomic_uint64* dst, c89atomic_uint64 expected, c89atomic_uint64 desired)
      |                                                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
_lib/miniaudio/miniaudio.h: In function ‘ma_result ma_wav_get_cursor_in_pcm_frames(ma_wav*, ma_uint64*)’:
_lib/miniaudio/miniaudio.h:61589:76: error: invalid conversion from ‘ma_uint64*’ {aka ‘long unsigned int*’} to ‘drwav_uint64*’ {aka ‘long long unsigned int*’} [-fpermissive]
61589 |         drwav_result wavResult = drwav_get_cursor_in_pcm_frames(&pWav->dr, pCursor);
      |                                                                            ^~~~~~~
      |                                                                            |
      |                                                                            ma_uint64* {aka long unsigned int*}
_lib/miniaudio/miniaudio.h:60105:82: note:   initializing argument 2 of ‘drwav_result drwav_get_cursor_in_pcm_frames(drwav*, drwav_uint64*)’
60105 | DRWAV_API drwav_result drwav_get_cursor_in_pcm_frames(drwav* pWav, drwav_uint64* pCursor);
      |                                                                    ~~~~~~~~~~~~~~^~~~~~~
_lib/miniaudio/miniaudio.h: In function ‘ma_result ma_wav_get_length_in_pcm_frames(ma_wav*, ma_uint64*)’:
_lib/miniaudio/miniaudio.h:61619:76: error: invalid conversion from ‘ma_uint64*’ {aka ‘long unsigned int*’} to ‘drwav_uint64*’ {aka ‘long long unsigned int*’} [-fpermissive]
61619 |         drwav_result wavResult = drwav_get_length_in_pcm_frames(&pWav->dr, pLength);
      |                                                                            ^~~~~~~
      |                                                                            |
      |                                                                            ma_uint64* {aka long unsigned int*}
_lib/miniaudio/miniaudio.h:60106:82: note:   initializing argument 2 of ‘drwav_result drwav_get_length_in_pcm_frames(drwav*, drwav_uint64*)’
60106 | DRWAV_API drwav_result drwav_get_length_in_pcm_frames(drwav* pWav, drwav_uint64* pLength);
      |                                                                    ~~~~~~~~~~~~~~^~~~~~~
mackron commented 1 year ago

Thanks for the report. Those errors are coming for amalgamated projects which are using their own sized type declarations which differ slightly. I think the correct fix is to update the amalgamation tool I use so that the amalgamated libraries use miniaudio's types instead of their own.

I'll have a look into this one.

mackron commented 1 year ago

I've done a partial fix for this. It's in the dev branch. It should address the c89atomic errors, but the drwav ones will still be there for the moment. Is that the full list of errors by the way?

Spotlightsrule commented 1 year ago

Yes. That's the full list

mackron commented 1 year ago

I've done a big rework of the amalgamation of c89atomic and dr_wav which should address all of these errors. Changes are in the dev branch. Are you able to give that a try?

Spotlightsrule commented 1 year ago

Yes, I can try that. Thanks for the rapid deployment of a fix.

Spotlightsrule commented 1 year ago

Switched to the dev branch and I am now getting the following compiler errors regardless of whether I use the C11 fixed width ints or not. The rest of the code remains unchanged

$ g++ miniaudio-loop.cpp -o miniaudio-loop && miniaudio-loop 
In file included from miniaudio-loop.cpp:6:
_lib/miniaudio/miniaudio.h: In function ‘void* ma_dlopen(ma_log*, const char*)’:
_lib/miniaudio/miniaudio.h:17745:46: error: ‘RTLD_NOW’ was not declared in this scope
17745 |         handle = (ma_handle)dlopen(filename, RTLD_NOW);
      |                                              ^~~~~~~~
_lib/miniaudio/miniaudio.h:17745:46: note: the macro ‘RTLD_NOW’ had not yet been defined
In file included from /usr/include/dlfcn.h:27,
                 from _lib/miniaudio/miniaudio.h:17847:
/usr/include/x86_64-linux-gnu/bits/dlfcn.h:25: note: it was later defined here
   25 | #define RTLD_NOW        0x00002 /* Immediate function call binding.  */
      | 
_lib/miniaudio/miniaudio.h:17745:29: error: ‘dlopen’ was not declared in this scope; did you mean ‘popen’?
17745 |         handle = (ma_handle)dlopen(filename, RTLD_NOW);
      |                             ^~~~~~
      |                             popen
_lib/miniaudio/miniaudio.h: In function ‘void ma_dlclose(ma_log*, ma_handle)’:
_lib/miniaudio/miniaudio.h:17771:9: error: ‘dlclose’ was not declared in this scope; did you mean ‘pclose’?
17771 |         dlclose((void*)handle);
      |         ^~~~~~~
      |         pclose
_lib/miniaudio/miniaudio.h: In function ‘void (* ma_dlsym(ma_log*, ma_handle, const char*))()’:
_lib/miniaudio/miniaudio.h:17796:21: error: ‘dlsym’ was not declared in this scope; did you mean ‘ma_dlsym’?
17796 |     proc = (ma_proc)dlsym((void*)handle, symbol);
      |                     ^~~~~
      |                     ma_dlsym
mackron commented 1 year ago

Thanks. My mistake. That was due to an unrelated change I made yesterday. Should be fixed in the dev branch now.

Spotlightsrule commented 1 year ago

Yes its fixed now, and I can use fixed-width ints from the stdlib. Thanks.