-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
core/debug: detect number of arguments #20166
base: master
Are you sure you want to change the base?
Conversation
@@ -44,16 +44,19 @@ extern "C" { | |||
*/ | |||
#ifdef DEVELHELP | |||
#include "cpu_conf.h" | |||
#define DEBUG_PRINT(...) \ | |||
#define DEBUG_PRINT(X, ...) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not standard compliant, as the C standard requires at least on argument to be present for the ...
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the C23 working draft has it so its probably well supported on other compilers (than GCC an clang) too
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3096.pdf p178:
If there is a ... in the identifier-list in the macro definition, then the trailing arguments (if any),
including any separating comma preprocessing tokens, are merged to form a single item: the variable
arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define THREAD_EXTRA_STACKSIZE_PRINTF 42
#define NULL ((void *)0)
typedef struct thread {
/* bla blah doesn't matter */
unsigned stack_size;
} thread_t;
extern int printf(const char *restrict format, ...);
extern int puts(const char *s);
extern thread_t * thread_get_active(void);
#define DEBUG(X, ...) \
do { \
if (sizeof((const char[]){"empty"#__VA_ARGS__}) == sizeof((const char[]){"empty"}))\
printf(X, ##__VA_ARGS__);\
else {\
if ((thread_get_active() == NULL) || \
(thread_get_active()->stack_size >= \
THREAD_EXTRA_STACKSIZE_PRINTF)) { \
printf(X, ##__VA_ARGS__); \
} \
else { \
puts("Cannot debug, stack too small. Consider using DEBUG_PUTS()."); \
} }\
} while (0)
extern int a, b, c, d;
void foo(void) {
DEBUG("Hallo\n");
DEBUG("a = %d\n", a);
DEBUG("a = %d, b = %d\n", a, b);
DEBUG("a = %d, b = %d, c = %d\n", a, b, c);
}
$ clang -c -Os -std=c2x -Weverything -o test.o test.c
test.c:16:21: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
16 | printf(X, ##__VA_ARGS__);\
| ^
test.c:21:29: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
21 | printf(X, ##__VA_ARGS__); \
| ^
test.c:16:23: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
16 | printf(X, ##__VA_ARGS__);\
| ^
test.c:21:31: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
21 | printf(X, ##__VA_ARGS__); \
| ^
test.c:16:23: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
16 | printf(X, ##__VA_ARGS__);\
| ^
test.c:21:31: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
21 | printf(X, ##__VA_ARGS__); \
| ^
test.c:16:23: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
16 | printf(X, ##__VA_ARGS__);\
| ^
test.c:21:31: warning: token pasting of ',' and __VA_ARGS__ is a GNU extension [-Wgnu-zero-variadic-macro-arguments]
21 | printf(X, ##__VA_ARGS__); \
| ^
test.c:30:6: warning: no previous prototype for function 'foo' [-Wmissing-prototypes]
30 | void foo(void) {
| ^
test.c:30:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
30 | void foo(void) {
| ^
| static
9 warnings generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<source>: .. warning: no previous prototype for function 'foo' [-Wmissing-prototypes]
are you sure that is a applicable warning level ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define DEBUG(X, ...) \
do { \
if (sizeof((const char[]){"empty"#__VA_ARGS__}) == sizeof((const char[]){"empty"}))\
printf(X __VA_OPT__(,) __VA_ARGS__);\
else {\
if ((thread_get_active() == NULL) || \
(thread_get_active()->stack_size >= \
THREAD_EXTRA_STACKSIZE_PRINTF)) { \
printf(X __VA_OPT__(,) __VA_ARGS__); \
} \
else { \
puts("Cannot debug, stack too small. Consider using DEBUG_PUTS()."); \
} }\
} while (0)
would be the solution following the c2x draft but clang doesn't like that either :
-Os -std=c2x -Weverything
Output of x86-64 clang 17.0.1 (Compiler #1)
<source>:32:20: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
32 | DEBUG("Hallo\n");
seems like clangs warnings are not up to date
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NACK.
- using GCC specifics
- making the macro larger instead of removing it
- really, "detect number of arguments" in the preprocessor? RIOT markets itself as "the friendly operating system", and this definitely isn't.
Btw: I don't think we would need the bail out mechanism anymore if we would switch to picolibc. Maybe this is something that we could push instead and get rid of the bail out entirely? |
Contribution description
this adds a number of arguments detection for the DEBUG_PRINT Macro to avoid the not very helpful "I don't print because the thread stack is to small" for cases that are cought by the printf to puts conversion (which is active starting on -O0 on gcc and llvm
Testing procedure
Debug print?
Issues/PRs references