C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Type-safe printf and auto

From: Alejandro Colomar (man-pages) <"Alejandro>
Date: Sun, 12 Mar 2023 20:08:35 +0100
Hi,

On Sun, Mar 12, 2023, 17:38 Robin Rowe via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> While type-safe iostream is the modern way, we still have the not so
> type-safe printf. Modern compilers help by warning when encountering a
> type mismatch on printf, such as:
>
> int i = 1;
> printf("Value of i is %u",i);// Warning: use %d
>
> Anyone who does C/C++ code refactoring is aware of the side effect when
> correcting the type of a variable, that it causes printf args mismatches
> due to the type change:
>

If you want to do it in C, you can.

For printing the value, whatever the type is, you should use "%jd" and cast
the value to (intmax_t). Whatever it is, it will be printed. If it's a
huge unsigned value, you might see it changed to a signed negative, but
that's a minor issue, and in places you expect that, you can use "%ju" and
(uintmax_t).

For the variable name, just search for the STRINGIFY() macro. It's worth
widely known:
<https://stackoverflow.com/a/54459521/6872717>.

And for it's type, you can use _Generic(). It's not available in C++, but
I'm sure there's some alternative with templates. Have a look here for the
C version:
<https://stackoverflow.com/a/17290414/6872717>.

Cheers,

Alex


> Before:
> size_t n = 5;
> int i = 1;// Wrong, causes warning below...
> if(i > n)... ;// Warning: signed/unsigned mismatch...
> printf("Value of i is %d",i);
> After:
> size_t n = 5;
> size_t i = 1; // Fixed, yay, but breaks printf...
> if(i > n)... ;
> printf("Value of i is %d",i);// Warning: use %zu
>
> Changing variable i to be the correct type breaks code using i with
> printf. Fixing one warning causes new warnings everywhere the variable
> is used with printf. In most cases, we simply want to print the value of
> the variable. Don't really care what type it is. Note that when the
> compiler outputs the printf type mismatch warning, it knows everything
> about variable i, including its type and name.
>
> Moreover, what about using printf with auto variables? It is necessary
> we know the type of auto, but we specified auto intending to avoid that.
>
> Wish we could do this:
>
> auto i = sizeof(int);
> printf("Value is %?, name is %??, type is %???",i,i,i);
>
> output: Value is 4, name is i, type is unsigned
>
> Furthermore, in C++ code it could be nice if printf gave the same output
> as cout for user-defined types:
>
> Point point(0,0,0);// My class Point with operator<<
> cout << point << endl;
> printf("%?\n",point);
>
> output: (0,0,0)
> (0,0,0)
>
> Thoughts? Suggestions?
>
> To propose above as standard, touching both C and C++, what would be the
> process?
>
> Robin
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2023-03-12 19:08:49