Yann Droneaud
Yann Droneaud

Reputation: 5463

Why this macro is defined as ({ 1; })?

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

Some links

Upvotes: 27

Views: 1249

Answers (3)

ugoren
ugoren

Reputation: 16441

A possible explanation is to prevent usage in undesirable situations.
This is useful to improve code portability - if another architecture's implementation of the macro would fail, we want this one to fail too.

Example: static int x = __clk_get(clk); - there's no sense in statically initializing with the clock.
With #define __clk_get(clk) (1), it will work.
With #define __clk_get(clk) ({ 1; }), it will fail.

Upvotes: 0

AnT stands with Russia
AnT stands with Russia

Reputation: 320531

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.

Upvotes: 9

manav m-n
manav m-n

Reputation: 11394

Why this macro is defined as ({ 1; })?

It all depends on the programmer's coding style. All it does is return the value 1. For example, on x86 arch in "include/asm-generic/clkdev.h", __clk_get is defined as

static inline int __clk_get(struct clk *clk) { return 1; }

Also in linux/arch/c6x/include/asm/clkdev.h

static inline int __clk_get(struct clk *clk)
{
        return 1;
}

Upvotes: 8

Related Questions