Linux の複数の ARM バックエンドで、ファイルにclkdev.h
次のマクロ定義が表示されます。
#define __clk_get(clk) ({ 1; })
たとえば、 ./arch/arm/mach-versatile/include/mach/clkdev.hを参照してください。
このマクロは、式での GCC 拡張ステートメントと宣言を使用しています
後で、このマクロはファイル./drivers/clk/clkdev.cの関数で使用されますclk_get_sys()
if (cl && !__clk_get(cl->clk))
cl = NULL;
ここで単純なマクロを使用しないのはなぜだろうと思っています:
#define __clk_get(clk) (1)
編集:
次のgrepパターンを使用して、カーネルソース全体でこの構成の他の使用法を見つけました。
grep -R '({[[:space:]]*[a-zA-Z0-9_()+=/!&*>., ?:-]\+[[:space:]]*;[[:space:]]*})' .
ここにいくつかの試合があります:
./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;})
[...]
注: この構文({if(put_user(d, (typeof (d)*)a)) return -EFAULT;})
は、複合ステートメントの適切な使用方法のようです。しかし、これはより典型的なものに置き換えることもできますdo { if(put_user(d, (typeof (d)*)a)) return -EFAULT; } while(0)
によって返される 1 つの一致grep
は興味深いものです。./include/asm-generic/bug.hには、./include の使用法に関するコメントがあります({ 0; })
。これは AndreyT の回答と まったく同じです。
実際、((void)0)
r 値として使用できないため、 を使用することはできません。
({ 0; })
それぞれの場合に働いています。
したがって、使用できるかどうかに関係なく値を返す関数のように使用できるマクロがある場合は、複合ステートメントが唯一のオプションのようです。
しかし__clkget()
、r値として他のものとして使用されることはありません