C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Explicit keyword for template parameters

From: Peter C++ <peter.cpp_at_[hidden]>
Date: Sun, 1 May 2022 08:41:51 +0200
in case of unwanted integral promotion you might want to look at my integer replacement library that does not silently promote and change signedness or signed integer overflow undefined behavior by employing enum class types:

https://github.com/PeterSommerlad/PSsimplesafeint

Regards
Peter

Sent from Peter Sommerlad's iPad
+41 79 432 23 32

> On 30 Apr 2022, at 10:07, Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> On Fri, Mar 25, 2022 at 11:09 AM organicoman wrote:
>>
>> Your proposal could be interesting.
>> But why do you want to explicitly write the type, if you can deduce it?
>
>
> One common debacle in C++ is unwanted integer promotion, especially
> for beginner programmers. Let's say we have a template function whose
> return type is the same as its parameter type:
>
> template<typename T>
> T Func(T const &arg) { /* Do something */ }
>
> And let's say we do this:
>
> int main(void)
> {
> char unsigned a = 7, b = 6;
>
> Func( a + b );
> }
>
> Lots of people at first glance will think here that 'Func' is being
> instantiated with the type "char unsigned", when really it's being
> instantiated with "int".
> If the template function, 'Func', will be frequently used in such a
> context, it would be better for the programmer to have to explicitly
> specify the type, either:
>
> Func<char unsigned>(a+b);
>
> or even:
>
> Func<decltype(a)>(a+b);
>
> In my day job I write C++ for an Arduino microcontroller. I went
> looking in my code just now to find the template function I wrote
> earlier this month. The following function performs the mathematical
> operation:
>
> a + b
>
> however if this operation results in overflow then it returns:
>
> std::numeric_limits<T>::max();
>
> So here's how I wrote the function:
>
> #include <type_tratis>
>
> template<typename T>
> typename std::common_type<T>::type Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
>
> My program runs on an Arduino microcontroller, however I also compile
> it as part of a simulator that runs on an x86_64 desktop PC. In the
> future the simulator might run on a different kind of desktop PC, and
> we might change to a 16-Bit or 64-Bit microcontroller (or even 8-Bit
> -- Arduino has a C++ compiler for 8-Bit). Because of the differences
> in architecture here, I am very particular about integer types, using
> "std::uint16_t" and "std::int32_t" instead of short, int, long (and
> also watching out for the perils of integer promotion -- e.g. uint32_t
> might promote to a signed 64-Bit number). When a programmer uses my
> function "Add_Or_Max", I want it to stick out like a sore thumb in the
> code which integer type they're using, e.g.:
>
> #include <cstdint>
> using std::uint16_t;
>
> uint16_t my_global_var;
>
> int main(void)
> {
> Add_Or_Max( my_global_var, 52u ); // I don't want this to compiler
>
> Add_Or_Max<uint16_t>( my_global_var, 52u ); // I want this to compile
> }
>
> And so I think it would be great if we could have explicit template
> parameters as follows:
>
> template<explicit typename T>
> T Add_Or_Max(T const a, T const b)
> {
> static_assert( false == std::numeric_limits<T>::is_signed,
> "Add_Or_Max can only be used with an unsigned integer type" );
>
> if ( a > (std::numeric_limits<T>::max() - b) )
> {
> return std::numeric_limits<T>::max();
> }
> else
> {
> return a + b;
> }
> }
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2022-05-01 06:41:56