boostorg / boostorg/units

Explicit construction of quantities using units that are not defined in system compiles but mathematically fails

Open
#59 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
39
Forks
60
PR merge metrics
No merged PRs in 30d

Description

If I define a unit in a system that doesn't have this base dimension, e.g. angular_velocity in the degrees system:

```
quantity> angular_vel_deg(30*degree::degrees/si::seconds);
```

This compiles fine, and explicit conversions also compile fine:

```
quantity> angular_vel_si(angular_vel_deg);
```

However when I go to run it, I get `angular_vel_si` as `30 rad/s` rather than the expected `0.523 rad/s`

The fact that this compiles seems to be a bug to me, but most importantly I'd like to be able to detect this situation (ideally with a static_assert) so that I don't have code that compiles but performs incorrect conversions.

With a few hours digging around I couldn't find a satisfactory way to do this, though I think it might be related to https://github.com/boostorg/units/issues/36 but the proposed fix (https://github.com/boostorg/units/pull/37) didn't fix my issue.

Here's my full minimal test case. Thanks in advance for any help you can provide:

```
#include "units/include/boost/units/systems/si.hpp"
#include "units/include/boost/units/systems/angle/degrees.hpp"
#include
#include
#include

int main()
{
double eps = std::numeric_limits::epsilon();


using boost::units::unit;
using boost::units::quantity;
namespace si = boost::units::si;
namespace degree = boost::units::degree;

// angle, works as expected
{
using boost::units::plane_angle_dimension;
quantity> angle_deg(30*degree::degrees);
quantity> angle_si(angle_deg);

std::cout << "Degrees: " << angle_deg.value() << ", radians: " << angle_si.value() << std::endl;

assert(std::abs(angle_deg.value()-angle_si.value()) > eps);
}

// angular velocity: fails but more importantly, it compiles (when I feel that it shouldn't)
{
using boost::units::angular_velocity_dimension;

quantity> angular_vel_deg(30*degree::degrees/si::seconds);
quantity> angular_vel_si(angular_vel_deg);

std::cout << "Degrees/sec: " << angular_vel_deg.value() << ", radians/sec: " << angular_vel_si.value() << std::endl;

assert(std::abs(angular_vel_deg.value()-angular_vel_si.value()) > eps);
}

}
```

Output:
```
Degrees: 30, radians: 0.523599
Degrees/sec: 30, radians/sec: 30
a.out: test2.cpp:38: int main(): Assertion `std::abs(angular_vel_deg.value()-angular_vel_si.value()) > eps' failed.
zsh: IOT instruction (core dumped) ./a.out
```

Expected (or compile failure would also be acceptable):
```
Degrees: 30, radians: 0.523599
Degrees/sec: 30, radians/sec: 0.523599
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.