Fix build where major() and minor() are macros - #338
Open
guicybercode wants to merge 1 commit into
Open
guicybercode wants to merge 1 commit into
guicybercode wants to merge 1 commit into
Conversation
FreeBSD's <sys/types.h> and glibc's <sys/sysmacros.h> define major() and
minor() as function-like macros and, unlike Apple's headers, keep them as
macros in C++. nam::Version's member-initializer list read `major(major)`,
which expanded, so NAM/get_dsp.h failed to compile for any consumer that
included one of those headers first:
NAM/get_dsp.h:30:5: error: expected class member or base class name
Brace-init the members instead. A function-like macro only expands when the
identifier is followed by `(`, so `major{major}` is left alone; `int major;`,
`parsed.major` and `std::to_string(major)` never expanded to begin with, which
makes lines 30-31 the only two expansion sites in the tree. The public members
keep their names, so this is not an API break.
The regression test defines the two macros itself rather than including
<sys/types.h>, so it reproduces the FreeBSD/glibc preprocessor state on every
platform, and is included first in run_tests.cpp so that NAM/get_dsp.h has not
already been parsed by an earlier test.
Validated on macOS/AppleClang: the new test fails to compile against the
unmodified header with the error above, and the full run_tests suite, both
benchmodel models and render all pass with the fix.
Fixes sdatkinson#304
|
The "fix" of { } init members is more of a workaround than an actual fix... the real fix would be to force apple to do things right in the first place. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #304.
The problem
<sys/types.h>on FreeBSD and<sys/sysmacros.h>on glibc definemajor()andminor()as function-like macros, and unlike Apple's headers they stay macros in C++.nam::Version's member-initializer list readmajor(major), which expanded, soNAM/get_dsp.hfailed to compile for any consumer that included one of those headers first:The fix
Brace-init the members. A function-like macro only expands when the identifier is followed by
(, somajor{major}is left alone, whileint major;,parsed.major > latest.majorandstd::to_string(major)never expanded in the first place. GreppingNAM/andtools/formajor *(/minor *(confirms lines 30-31 were the only two expansion sites in the tree, which is why this is a two-line change.The public
major/minor/patchmembers keep their names, so this is not an API break and no consumer needs to change.@DeimosLabs suggested renaming the members to
major_version/minor_versioninstead. That works too, but it breaks the public API and would need the eight sites intools/test/test_get_dsp.cpp:293-363that mutate.minor/.patchupdated. Happy to switch to the rename if you would rather have the more obvious spelling — just say the word.The test
tools/test/test_get_dsp_sys_types.cppdefines the two macros itself rather than including<sys/types.h>. That matters: Apple's header deliberately uses inline functions instead of macros in C++ (see the comment insys/types.h), so including it would make the test a no-op on macOS. Defining them directly reproduces the FreeBSD/glibc preprocessor state on every platform, including in CI.Two details worth flagging for review:
run_tests.cpp. If an earlier test had already pulled inNAM/get_dsp.h,#pragma oncewould make the include a no-op and the test would prove nothing.get_dsp.h's dependency closure and#undef'd at the end. Expanding them inside libc++'s own headers is a different, unrelated failure, and leaving them defined would leak into every test included afterwards.Validation
On macOS / AppleClang, Debug build:
NAM/get_dsp.hand rebuilding.)run_tests— all pass.benchmodel example_models/wavenet.nam,benchmodel example_models/lstm.nam, andrenderonexample_audio/input.wav— all fine.I do not have a FreeBSD box, so the FreeBSD build itself is unverified; the macro simulation is what I could test directly.