NOTE: Please always add static_assert
on datatype before using FmtCore::format
#4642
Replies: 7 comments
-
@WHUweiqingzhou FYI |
Beta Was this translation helpful? Give feedback.
-
Most compilers provide a "-Wformat" option for basic type checks for printf/sprintf/..., which would emit a warning message when there is a type mismatch. For example, compiling the following code #include <cstdio>
int main() {
double d = 3;
std::snprintf(nullptr, 0, "%4i", d);
return 0;
} will get something like
I'm not sure if "-Wformat" is enabled by default [at least it is so on my everyday compiler gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)], but even it is enabled, the real question is, "-Wformat" is merely a compile-time check that is unable to be carried out for argument types agains a format string passed via function argument, as it is in FmtCore. That is to say, "-Wformat" would fail to detect bugs like #include <cstdio>
void foobar(const char* fmt, double i) {
std::snprintf(nullptr, 0, fmt, i);
}
int main() {
foobar("%4i", 3.0);
return 0;
} It might, however, be possible to let snprintf knows the format string during compilation, as long as the format string is a const expression (e.g., making "foobar" a function template and fmt a template parameter). Unfortunately, using string literals as template parameters is a c++20 feature; achieving this within c++11, if possible, might need some metaprogramming. |
Beta Was this translation helpful? Give feedback.
-
@jinzx10 IMHO using macro definition would be a good replacement #include <cstdio>
#define foobar_safe(fmt, i) std::snprintf(nullptr, 0, fmt, i)
int main() {
foobar_safe("%4i", 3.0);
} This grammar generates warning correctly. |
Beta Was this translation helpful? Give feedback.
-
@caic99 #include <cstdio>
#define __FMTCORE_DATA_CHECK__(fmt, ...) std::snprintf(nullptr, 0, fmt, __VA_ARGS__)
int main() {
const int right = 3;
const double wrong = 3.0;
__FMTCORE_DATA_CHECK__("%4d%4d", right, wrong);
} |
Beta Was this translation helpful? Give feedback.
-
I think in the beginning of the issue, there should be a link to explain what is 'formatter' @kirk0830 |
Beta Was this translation helpful? Give feedback.
-
Thanks, I have added a short explanation about formatter in issue descrption |
Beta Was this translation helpful? Give feedback.
-
I move this issue to discussion |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Describe the Code Quality Issue
After a very long time debugging, @jinzx10, @caic99 and I find the bug reported by issue #4540.
See the following code piece:
abacus-develop/source/module_cell/klist.cpp
Line 776 in db90f92
what will happen if:
abacus-develop/source/module_cell/klist.cpp
Lines 944 to 953 in db90f92
?
It will trigger an undefined behavior because the double is parsed like int by
formatter
(the ABACUS in-built library for formatting strings, implemented inmodule_base/formatter.h
), that cases recent failure in integrated test.The implementation of function
FmtCore::format
is quite simple:abacus-develop/source/module_base/formatter.h
Lines 40 to 48 in db90f92
But the c-style function
snprintf
itself cannot identify the datatype. So I would suggest to use something likestatic_assert
before using this function.Additional Context
No response
Task list for Issue attackers (only for developers)
Beta Was this translation helpful? Give feedback.
All reactions