-
Notifications
You must be signed in to change notification settings - Fork 16
Description
Summary
When trying to model angles as a dimensionless quantity (SI: radian is dimensionless), the library rejects quantity<dimensionless_d> with:
static_assert failed: 'quantity dimensions must not all be zero'
even if PHYS_UNITS_COLLAPSE_TO_REP is explicitly set to 0. The reason is that quantity.hpp uses #if defined(PHYS_UNITS_COLLAPSE_TO_REP) instead of a value check, so the assertion is enabled whenever the macro is defined (including when set to 0).
Affected code
In phys/units/quantity.hpp (current HEAD as of <insert date/commit>):
#ifndef PHYS_UNITS_COLLAPSE_TO_REP
# define PHYS_UNITS_COLLAPSE_TO_REP 1
#endif
#if defined( PHYS_UNITS_COLLAPSE_TO_REP )
static_assert( has_dimension, "quantity dimensions must not all be zero" );
#endif
Because the file defines the macro if it’s missing, defined(PHYS_UNITS_COLLAPSE_TO_REP) is always true, which trips the assert even when consumers pass -DPHYS_UNITS_COLLAPSE_TO_REP=0.
Minimal repro
// Build with: -DPHYS_UNITS_COLLAPSE_TO_REP=0
#include "phys/units/quantity.hpp"
using namespace phys::units;
struct EulerAngles
{
quantity<dimensionless_d> roll{};
quantity<dimensionless_d> pitch{};
quantity<dimensionless_d> yaw{};
};
// Fails to compile with: static_assert failed: 'quantity dimensions must not all be zero'
Actual: Compilation fails with the static_assert.
Expected: With PHYS_UNITS_COLLAPSE_TO_REP=0, dimensionless quantities should be allowed (no collapse), so quantity<dimensionless_d> should compile.
Suggested fix
Switch the guard from macro-is-defined to a macro value check:
-#if defined( PHYS_UNITS_COLLAPSE_TO_REP )
+#if PHYS_UNITS_COLLAPSE_TO_REP
static_assert( has_dimension, "quantity dimensions must not all be zero" );
#endif
(Apply to all occurrences where the macro controls dimensionless handling.)
This preserves the current default (1 → collapse to representation type) while allowing consumers to opt out cleanly with PHYS_UNITS_COLLAPSE_TO_REP=0.
Workarounds
Patch quantity.hpp locally as above (or shadow the header earlier in the include path).
There is no reliable way to “undefine” the macro from user code because the header re-defines it via #ifndef.
Environment
Compiler: MSVC 19.xx (Visual Studio 2022)
C++ standard: C++20
OS: Windows 11
Build system: Unreal Engine 5.6 modules (but the repro above is plain C++)
Motivation / Context
Angles are naturally modeled as dimensionless in SI, but many users still want type safety via quantity<dimensionless_d>. Being able to set PHYS_UNITS_COLLAPSE_TO_REP=0 is important to keep angle quantities from collapsing to raw scalars. The current defined(...) check prevents that.