このマクロが ({ 1; }) として定義されているのはなぜですか? 質問する

このマクロが ({ 1; }) として定義されているのはなぜですか? 質問する

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の使用に関するコメントがあります({ 0; })。これは全く同じです答えアンドレイT

((void)0)実際、は r 値として使用できないため、 は使用できません。({ 0; })はそれぞれのケースで機能しています。

したがって、使用できる値を返す関数のように使用できるマクロがある場合、複合ステートメントが唯一の選択肢であると思われます。

しかし、__clkget()r値として他の用途に使われることはない

いくつかのリンク

ベストアンサー1

-Wallモードでは、スタンドアロン(1);式ステートメントは「効果のないステートメント」警告を生成しますが、スタンドアロン({ 1; });式ステートメントは警告を生成しないことに気づきました。

おそらく、コードのどこかで、__clk_get結果を無視するスタンドアロン呼び出しが行われることになります。(1)定義では、そのような呼び出しに対して警告が出されますが、({ 1; })他のコンテキストでは同じ効果を生み出しながら、警告は出ません。

おすすめ記事