Description
To reproduce:
#include <array>
#include <tuple>
using MonthArray = std::array<int, 12>;
using ZodiacArray = std::array<int, 12>;
static_assert(std::tuple_size<MonthArray>::value == std::tuple_size<ZodiacArray>::value);
static_assert(std::tuple_size_v<MonthArray> == std::tuple_size_v<ZodiacArray>);
Output:
<source>:7:50: warning: both sides of operator are equivalent [misc-redundant-expression]
7 | static_assert(std::tuple_size<MonthArray>::value == std::tuple_size<ZodiacArray>::value);
| ^
<source>:8:45: warning: both sides of operator are equivalent [misc-redundant-expression]
8 | static_assert(std::tuple_size_v<MonthArray> == std::tuple_size_v<ZodiacArray>);
| ^
2 warnings generated.
In reality MonthArray
and ZodiacArray
may be defined far away from each other, or even in completely unrelated modules. When we happen to use MonthArray
and ZodiacArray
together, a reader without enough context is likely unaware that they are the same type, and we want to use a static_assert
to remind the reader that they do have the same value
. (We could also use std::same_as<MonthArray, ZodiacArray>
but sometimes we only care about their lengths in the surrounding code)
In this case comparing MonthArray
and ZodiacArray
shouldn't be redundant. Such expressions should only be redundant if the two types are spelled in exactly the same way.
There has been a similar issue #118885 where the final resolution was that comparing different macros expanding to the same constant is non-redundant. This issue is in principal similar, but regarding to type aliases instead of macros.