Bug 21605 – Instead of giving error on printf format mismatch, correct it

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2021-02-03T07:59:24Z
Last change time
2024-12-13T19:14:26Z
Assigned to
No Owner
Creator
Walter Bright
See also
https://issues.dlang.org/show_bug.cgi?id=24133
Moved to GitHub: dmd#19864 →

Comments

Comment #0 by bugzilla — 2021-02-03T07:59:24Z
For example, import core.stdc.stdio; void test(int i) { printf("the number is %s\n", i); } gives: Error: argument `i` for format specification `"%s"` must be `char*`, not `int` I propose that instead, if the format specifier is `%s`, the format string literal gets rewritten to use the correct format specifier for type `int`, i.e. code is generated for: printf("the number is %d\n", i); For most uses of printf, using %s will "just work", making it usable with generic code. If the format specifier is not `%s`, and is mismatched with its corresponding argument, there is no change in behavior (i.e. the mismatch error is given). The baseline implementation should handle all integral and floating point arguments. Extensions: 1. Transferring the modifiers like field width over to the replacement format specifier. 2. Replacing `%x` format specifiers with `%a` for floating point arguments. 3. Handling D strings by replacing the format specifier with `%.*s` and rewriting the argument to give the length and pointer. This enhancement would be added to the existing code that does the printf format/argument checking. The user advantages are: 1. works with generic code 2. reduces the number of recompiles necessary to fix printf mismatch errors 3. reduces the inherent frustration of the compiler knowing what the fix is but demanding that the user apply the fix 4. user can change the types of variables without having to go through and adjust all the printf formats
Comment #1 by pro.mathias.lang — 2021-02-03T10:13:43Z
That sounds like a lot of magic for `printf`. What's the advantage over using, say, `writeln` ? And if it's only `-betterC` then it's rather simple to provide a library implementation that calls `printf` under the hood, no need to add this in the compiler.
Comment #2 by dkorpel — 2021-02-03T10:36:13Z
I would not want to rely on compiler magic to rewrite a faulty format string into a correct one. You even said yourself: > I used to write macros in C named "printf" that would muck about with the arguments, > add some logic, then call the real printf. After a few years I got tired of them, > and put them in a bag with some rocks and threw it in the swamp. https://forum.dlang.org/post/[email protected] > It's kinda trivially obvious that someone can write their own functions to do > things, but pretending it is printf by naming it printf just puts a layer of > confusion in for the reader. printf is so ubiquitous that it brings > expectations when saying printf can be called that printf is actually being > called, rather than some intermediary one must write oneself. https://forum.dlang.org/post/[email protected] This is essentially such an intermediary function, only it's always inlined and implemented in the compiler. Ways this could backfire are: - The code is compiled with an older D compiler that doesn't apply the fix - printf arguments are copied to a third party 'my_printf' function that is not annotated with pragma(printf) - Someone unaware of D's printf magic translates D code to C Proposing the correct format specifier for the type (instead of only the correct type for the format specifier) in the error message seems like a good idea.
Comment #3 by robert.schadek — 2024-12-13T19:14:26Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19864 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB