In multiple ARM back-end of Linux, I'm seeing in files clkdev.h
this macro definition:
#define __clk_get(clk) ({ 1; })
See for example ./arch/arm/mach-versatile/include/mach/clkdev.h
This macro is using GCC extension Statements and Declarations in Expressions
Later this macro is used in file ./drivers/clk/clkdev.c, in function clk_get_sys()
if (cl && !__clk_get(cl->clk)) cl = NULL;
I'm wondering why not using here a simple macro:
#define __clk_get(clk) (1)
EDIT:
I've found some other usage of this construct throughout the kernel sources using the following grep pattern:
grep -R '({[[:space:]]*[a-zA-Z0-9_()+=/!&*>., ?:-]\+[[:space:]]*;[[:space:]]*})' .
Here's some of the matches:
./kernel/trace/trace_selftest.c:# define trace_selftest_startup_dynamic_tracing(trace, tr, func) ({ 0; }) ./kernel/profile.c:#define create_hash_tables() ({ 0; }) ./include/asm-generic/bug.h: * Use of ({0;}) because WARN_ON_SMP(x) may be used either as ./include/asm-generic/bug.h:# define WARN_ON_SMP(x) ({0;}) ./include/linux/key.h:#define key_get(k) ({ NULL; }) ./include/linux/key.h:#define key_get(k) ({ NULL; }) ./include/linux/audit.h:#define audit_alloc(t) ({ 0; }) ./include/linux/audit.h:#define audit_bprm(p) ({ 0; }) ./include/linux/audit.h:#define audit_sockaddr(len, addr) ({ 0; }) ./include/linux/audit.h:#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; }) ./include/linux/audit.h:#define audit_log_start(c,g,t) ({ NULL; }) ./include/linux/atalk.h:#define atalk_proc_init() ({ 0; }) ./include/linux/ftrace.h:#define register_ftrace_function(ops) ({ 0; }) ./include/linux/ftrace.h:#define unregister_ftrace_function(ops) ({ 0; }) ./include/linux/ftrace.h:#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; }) ./include/linux/ftrace.h:#define ftrace_set_filter(ops, buf, len, reset) ({ -ENODEV; }) ./include/linux/ftrace.h:#define ftrace_set_notrace(ops, buf, len, reset) ({ -ENODEV; }) ./include/linux/cpu.h:#define unregister_hotcpu_notifier(nb) ({ (void)(nb); }) ./include/linux/proc_fs.h:#define proc_net_fops_create(net, name, mode, fops) ({ (void)(mode), NULL; }) ./arch/powerpc/include/asm/pgtable-ppc64.h:#define pgd_set(pgdp, pudp) ({pgd_val(*(pgdp)) = (unsigned long)(pudp);}) ./arch/sh/math-emu/math.c:#define WRITE(d,a) ({if(put_user(d, (typeof (d)*)a)) return -EFAULT;}) ./arch/sh/math-emu/math.c:#define READ(d,a) ({if(get_user(d, (typeof (d)*)a)) return -EFAULT;}) [...]
Note: the construct ({if(put_user(d, (typeof (d)*)a)) return -EFAULT;})
seems to be a good usage of the compound statement. But this can also be replaced by more typical do { if(put_user(d, (typeof (d)*)a)) return -EFAULT; } while(0)
One match returned by grep
is interesting: in ./include/asm-generic/bug.h there's a comment of usage of ({ 0; })
. This is quite the same answer of AndreyT.
Indeed, one cannot use ((void)0)
, since it won't be usable as a r-value. ({ 0; })
is working in each case.
So if you have a macro that can used like a function returning a value that can be used or not, the compound statement seems to be your only option.
But __clkget()
is never used as anything else as a r-value
Inside of a C source file, you can use the #ifdef macro to check if a macro is defined.
In the C Programming Language, the #define directive allows the definition of macros within your source code. These macro definitions allow constant values to be declared for use throughout your code. Macro definitions are not variables and cannot be changed by your program code like variables.
A macro is an automated input sequence that imitates keystrokes or mouse actions. A macro is typically used to replace a repetitive series of keyboard and mouse actions and used often in spreadsheets and word processing applications like MS Excel and MS Word. The file extension of a macro is commonly . MAC.
There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls. You may define any valid identifier as a macro, even if it is a C keyword.
I notice that in -Wall
mode a standalone (1);
expression statement generates a "statement with no effect" warning, while a standalone ({ 1; });
expression statement produces no warnings.
Maybe somewhere in the code they somehow end up with standalone __clk_get
calls that ignore the result. The (1)
definition would result in warning for such calls, while ({ 1; })
keeps it quiet while producing the same effect in other contexts.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With