Details
-
Task
-
Status: In Review (View Workflow)
-
Minor
-
Resolution: Unresolved
-
None
Description
It is easy to pass wrong arguments in `my_error`: it is vararg, and not printf-like.
One common mistake is passing LEX_CSTRING instead of char*.
1. We can protect from LEX_CSTRING by implementing variadic template guard, forbidding, or implicitly converting some arguments by a sane set of rules, e.g.:
LEX_CSTRING -> char*,
|
anything other -> _error_
|
(TBD)
|
See also midenok's idea here: https://github.com/tempesta-tech/mariadb/issues/325
It will be still possible to pass int instead of char*, etc.
So, additionally, we can parse a format string and convert an argument to a correct parameter, or throw an assertion.
2. The above approach will reveal errors at runtime, and only for tested cases. We can do it in buildtime, although it will not cover all the cases when error code is determined at runtime:
template<int err_code, class... Args> |
int my_error_guard(Argc... args) |
{
|
static_assert(0); // arguments do not fit the prototype for specified error code |
}
|
|
template<class... Args> |
int my_error_guard<ER_CODE>(char* a, int b) |
{
|
my_error(ER_CODE, a, b);
|
}
|
|
// And so on |
When error code is dynamically resolved, it will fall back to dynamic check described above:
#define my_error(code, ...) \
|
(std::is_const<code>::value \
|
? my_error_guard<code>(__VA_ARGS__) \
|
: my_error(code, ##VA_ARGS))
|
This implementation will break when const, but not constexpr, error code is passed.
Attachments
Issue Links
- is blocked by
-
MDEV-25015 Custom formatting of strings in MariaDB queries
- Closed
- relates to
-
MDEV-21978 make my_vsnprintf to use gcc-compatible format extensions
- In Review