# Using custom aliases for physical units

Since I use C++ mainly to do physical calculations, I often come across the problem that I forget which units a certain variable is in, e.g. radian or degree, or meter vs. millimeter.

For this reason, I started using a custom header file defining my units, which is posted below. The basic idea is that I never create something like:

double myAngle = 10;


radian_t myAngle = 10;


Later, when passing it somewhere else, nobody will know whether it is in radian or degree. The upsides are listed below.

Are there any downsides to this?

Example implementation:

units.h:

#ifndef INCLUDE_UNITS_H_
#define INCLUDE_UNITS_H_

namespace units {
using meter_t  = double;
using newton_t = double;
using joule_t  = double;

} // units

#endif /* INCLUDE_UNITS_H_ */


sample.h:

using namespace units;

joule_t myEnergy (newton_t force, meter_t length)
{ joule_t myEnergy = force * length; }


The upsides are:

1. Fast unit lookup: In Eclipse, I only need to hover over a variable and instantly know the unit it is in, simple by seeing its type (meter_t myLength vs double myLength).

2. Easy debugging: The following code is obviously wrong, since Joule is Newton * meter:

joule_t myEnergy (newton_t force, millimeter_t length)
{ joule_t myEnergy = force * length; }


Is this function correct? Who knows!

double myEnergy (double force, double length)
{ double myEnergy = force * length; }

3. Overloading? In theory, I could even implement classes instead of using "using" declarations. Is that correct? This would let me overload the operators, making sure that sin.operator*(radian_t rad) is different from sin.operator*(degree_t deg)?

• Are you aware of Boost.Units? – Null Mar 27 '16 at 19:06
• I wasn't, thanks for mentioning it! This looks like what I was looking for. Sadly, my current project may only use the C++ Standard library, so Boost is out for now. – Thomas Mar 27 '16 at 22:38

There's a huge downside. One is that the compiler does not enforce your units. Your type names are aliases. You could pass a variable of type newton_t to a function expecting a meter_t. The only way to detect this error is via inspection. Your use of units give a false sense of security.
Another is that it invites you to create a plethora of units such as millimeter_t, etc. This will get you in trouble. My advice: Except for input and output, stick to strict SI units. No millimeters or kilometers, no minutes or days, no grams or tonnes. Lengths internally are always in meters, time durations are always in seconds, masses are always in kilograms (except for star and planet masses, which are expressed in meters3/seconds2; see https://en.wikipedia.org/wiki/Standard_gravitational_parameter).