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.
-
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