Print integral types as bit sizes instead of standard types
mhammerc opened this issue · 11 comments
Hello !
Another idea for improvements:
As for now, integral types are shown as int
, unsigned int
, etc
An idea is to print them as uint8
, int8
, uint16
, etc
This is because an int
does represent the size of the integral only for the platform it currently run.
I think a lot of developers do not use standard types (int
, char
, ...) but typedefs types (uint32_t
, uint8_t
, ...) just like me!
I think this is just a matter of updating theses lines with proper types even if there could be a better more generic way:
If you agree to this feature and you are not available, it will be my pleasure to provide a PR!
Thank you for the feedback.
I might not have considered every aspect of it, but it sounds like a good idea to me!
I personally also prefer uint64_t
over unsigned long
, etc.
Implementation-wise, I would suggest we introduce a helper macro:
#define DBG_MACRO_REGISTER_TYPE_NAME(type) \
inline std::string get_type_name(type_tag<type>) { return #type; }
DBG_MACRO_REGISTER_TYPE_NAME(uint8_t);
DBG_MACRO_REGISTER_TYPE_NAME(uint16_t);
DBG_MACRO_REGISTER_TYPE_NAME(uint32_t);
DBG_MACRO_REGISTER_TYPE_NAME(uint64_t);
DBG_MACRO_REGISTER_TYPE_NAME(int8_t);
DBG_MACRO_REGISTER_TYPE_NAME(int16_t);
DBG_MACRO_REGISTER_TYPE_NAME(int32_t);
DBG_MACRO_REGISTER_TYPE_NAME(int64_t);
DBG_MACRO_REGISTER_TYPE_NAME(std::string);
A few tests need to be adapted, but I'm fine with replacing int => int32_t
, unsigned short => uint16_t
, etc.
The README also needs to be adapted.
This sounds like a good place to put in a new config option. Put an ifdef
here to allow switching between using bits and standard types.
Ensures everyone is happy.
@sharkdp Good idea!
@DerekCresswell It's a good idea as it would not require any additional engineering!
I would try to avoid adding additional configuration flags. dbg.h
is designed to work "out of the box". Adding another compile-time switch also increases the complexity of the code and the tests.
Instead, we could simply show both. Let's say a user prints an int
and int ~ int32_t
on his platform. We would then show something like
[tests.cpp:76 (main)] x = 42 (int ~ int32_t)
If !std::is_same<int, int32_t>::value
on this platform, we would only show int
.
I think there is no need to have a mandatory int == int32_t
.
We could not print _t
suffix, to keep only the essential part: [u]int<size * 8>
It is easy to write in plain C++ but require some additional code to write and maintain. It should also be possible to write it as constexpr
, so each template specialization result is stored in binary and compute is made at compile-time.
template <typename Type>
get_type()
{
std::string type_string {}; // or something without dynamic memory management
type_string.reserve(7); // max type size: uint128 -> 7 chars
// std::is_unsigned or something like this
// sizeof(Type) * 8
}
I think there is no need to have a mandatory
int == int32_t
.
you mean... even if sizeof(int) == 4
, we could have std::is_same<int, int32_t>::value
evaluate to false
?
No, sorry. I meant that we can compute int32
at run-time or compile-time instead of forcing associations like int = int32_t
!
I wouldn't force this association. I would test for it. Something like:
inline std::string get_type_name(type_tag<int>) {
return std::is_same<int, int32_t>::value ? "int ~ int32_t" : "int";
}
And yes, this function could be constexpr
if we can generally return a const char*
instead of a string.
inline std::string get_type_name(type_tag<int>) {
return std::is_same<int, int32_t>::value ? "int ~ int32_t" : "int";
}
I feel like with this implementation output for other class templates will be messy. For ex, outputs like these
[main.cc:21 (solve)] v = {} (std::vector<std::pair<int ~ int32_t, int ~ int32_t>>)
We could rather prefer bit size variant over the standard types when std::is_same_v<int, int32_t>
evaluates to true
and register all such associations using a macro as you suggested here. Something like
#define DBG_MACRO_REGISTER_TYPE_ASSOC(t_std, t_bit) \
inline std::string get_type_name(type_tag<t_std>) { \
return std::is_same<t_std, t_bit>::value ? #t_bit : #t_std; \
}
I feel like with this implementation output for other class templates will be messy.
True
We could rather prefer bit size variant over the standard types when
std::is_same_v<int, int32_t>
evaluates totrue
and register all such associations using a macro as you suggested here.
Sounds good to me!