0

In a piece of code, there is a type defined as a uint_fast16_t. Specifically:

typedef uint_fast16_t loc_t;

//And in stdint.h:
typedef unsigned long int   uint_fast16_t;

Unfortunately with fast types, the "name" is part of the contract. In that a programmer must be cognisant that the type might be wider than 16 bits, but in usage should treat it as if the valid range is the same as a uint16_t.

I wish to write a static assert that asserts this contract is still valid for loc_t. In other words "has this type changed in a way that suggest values outside of uint16_t's range are valid?" which translates to "has the assigned name of this type changed?".

In other words, is there some way to write a static assert such as the following?

//not good, since uint_fast_16_t is typedef'd as uint64_t, so the type of loc_t could change to uint_fast64_t and this would pass.
static_assert(std::is_same<loc_t, uint_fast16_t>::value, "");  

//What I would actually need
static_assert(std::is_same<nameoftype(loc_t), name(uint_fast16_t)>::value, "");  
Chuu
  • 4,301
  • 2
  • 28
  • 54
  • 5
    As far as I know, type alias are indistinguishable from the type they are an alias of, as far as the compiler is concerned. – François Andrieux Nov 07 '22 at 18:55
  • Maybe just get rid of `typedef` usage? - worked for me.. – Jesper Juhl Nov 07 '22 at 18:57
  • Just use the alias somewhere, e.g. `uint_fast16_t foo{};`, and the code will fail to compile if you change the `typedef`. (Also, use `using`.) – Enlico Nov 07 '22 at 19:00
  • std::numeric_limits::[max](https://en.cppreference.com/w/cpp/types/numeric_limits/max) perhaps? – Eljay Nov 07 '22 at 19:00
  • @Enlico `int_fastN_t` and `uint_fastN_t` are defined by the C++ standard to be included in cstdint/stdint.h, they're not user defined types. – Chuu Nov 07 '22 at 19:21
  • Nitpick: "[...] but in usage should treat it as if the valid range is the same as a uint16_t." is not technically true. If `uint_fast16_t` happens to be defined as a type larger than 16bits, then you are allowed to use those additional bytes and store numbers outside the 16bit range. The `INT_FAST[8,16,32,64]_MIN` and `[U]INT_FAST[8,16,32,64]_MAX` macros define the allowed value-range for fast types; as far as the compiler is concernced, any number between those two macros is valid for the given fast type. [godbolt example](https://godbolt.org/z/5YoqaMbKb) – Turtlefight Nov 07 '22 at 20:25
  • @Turtlefight I stand by my original statement. If you are intentionally storing values in a uint_fastN_t that would not fit into a uintN_t that is something I would consider at best a code smell. If you really want to store a 32-bit unsigned number in a uint_fast_N variable, then you should be choosing N to be 32. Even if it'll compile and appear to work fine with N=16. – Chuu Nov 07 '22 at 20:45
  • If just writing a comment near your typedef describing the choice of the type is not enough to achieve what you want, I guess, your problem is deeper than keeping the assigned type unchanged. – Kit. Nov 07 '22 at 21:05
  • @Kit The "deeper problem" here essentially is fast types are being used on one side of an API boundary, and I do not trust the API to not expand the valid range in the future by changing the fast type. I personally think fast types were a mistake, doubly so since changes in computer architecture means they're usually slower than using the "non-fast" type. – Chuu Nov 07 '22 at 21:10
  • If it's a 3rd party library and you don't expect its further deliveries to stick to this contract, I would recommend either acting as if they are already not sticking to the contract, or checking their source code for the presence of this typedef as a part of your CI scripts. – Kit. Nov 07 '22 at 21:26
  • @Chuu Why don't you use their `loc_t` typedef everywhere in your code? That way they can change it to whatever they want and your code can't break. My suggestion would be to essentially treat it like you would `pthread_t` - as an [opaque data type](https://stackoverflow.com/q/33285562/8411406) that could be of any size. [godbolt example](https://godbolt.org/z/qM6bos7qd) – Turtlefight Nov 08 '22 at 00:25

0 Answers0