gpt4 book ai didi

c - C中如何保证全局符号的唯一性并限制其作用域?

转载 作者:太空狗 更新时间:2023-10-29 15:04:21 25 4
gpt4 key购买 nike

下面是 Linux 内核中用于 per-cpu valuables 的技巧。正如评论所说,它可以实现这两个目标:

1.执行范围。

2.确保唯一性,即使是静态的。

魔术是这样玩的(为简单起见,我用一些 MACRO 代替):

/*
* __pcpu_scope_* dummy variable is used to enforce scope. It
* receives the static modifier when it's used in front of
* DEFINE_PER_CPU() and will trigger build failure if
* DECLARE_PER_CPU() is used for the same variable.
*
* __pcpu_unique_* dummy variable is used to enforce symbol uniqueness
* such that hidden weak symbol collision, which will cause unrelated
* variables to share the same address, can be detected during build.
*/
#define DECLARE_PER_CPU_SECTION(type, name, sec) \
extern __attribute__((section(".discard"), unused)) \
char __pcpu_scope_##name; \
extern __attribute__((section(sec))) __typeof__(type) name

#define DEFINE_PER_CPU_SECTION(type, name, sec) \
__attribute__((section(".discard"), unused)) char __pcpu_scope_##name; \
extern __attribute__((section(".discard"), unused)) \
char __pcpu_unique_##name; \
__attribute__((section(".discard"), unused)) char __pcpu_unique_##name; \
__attribute__((section(sec))) __attribute__((weak)) \
__typeof__(type) name

我的问题是

  1. 目标 1。它如何执行范围?它是不是这样工作的:

    当 DECLARE* 和 DEFINE* 存在于同一个翻译单元时,它把有问题的内部链接变量,因此,任何额外的 DECLARE*相同的变量将触发构建失败(因为他们不同意链接)

    但如果这是真的,那么

    • interal-linkage-receivement 是如何工作的?从C99 6.9.2.2(External object definitions)开始,这种情况只发生在tentative definition,但这种情况好像不是tentative definition
    • 这不会违反“一个定义和多个声明都可以”规则吗?
  2. 对于目标 #2,两个 __pcpu_unique_##name decalation(确切地说,一个是声明,另一个是定义)似乎与 __pcpu_scope_##name 发挥相同的 trcik,那么它是如何实现的有助于确保唯一性?

仅供引用,有问题的代码可以在这里查看: http://lxr.linux.no/linux+v3.9/include/linux/percpu-defs.h#L61

最佳答案

我不认为这是由编译器强制执行的。查看ARM vmlinux.lds.S , vmlinux.lds.hpercpu.h ; 链接器文件 被预处理以使用内核 配置变量。 ".discard" 部分是一堆符号,会导致多个定义的链接冲突;但是它们被丢弃并且没有变成二进制文件。

查看PER_CPUPER_CPU_FIRSTPER_CPU_SHARED_ALIGNED等。这些宏只需要一个输入名称

您的 扩展不太正确。

 #define DECLARE_PER_CPU_SECTION(type, name, sec)                        \
extern __attribute__((section(".discard"), unused)) \
char __pcpu_scope_##name; \
extern __attribute__((section(PER_CPU_BASE_SECTION sec))) __typeof__(type) name

sec参数实际上是一个子节;注意 PER_CPU_BASE_SECTION 和字符串连接。

据我了解,它接收静态修饰符... 似乎具有误导性。最好表达为如果 它接收...。所以这些情况是不同的,

static DEFINE_PER_CPU_PAGE_ALIGNED(... /* Cause error with DECLARE */
DEFINE_PER_CPU(unsigned int, irq_count) = -1; /* Fine with DECLARE */

无论如何,这不是由编译器强制执行的,而是由 GNU 链接器(或至少两者)执行的,因为重要的是这些值是缓存对齐的,在某些情况下缓存大小由 kbuild 基础设施配置。

同样重要的是要注意前面与代码生成相关的评论,

 * s390 and alpha modules require percpu variables to be defined as
* weak to force the compiler to generate GOT based external
* references for them. This is necessary because percpu sections
* will be located outside of the usually addressable area.
* This definition puts the following two extra restrictions when
* defining percpu variables.
*
* 1. The symbol must be globally unique, even the static ones.
* 2. Static percpu variables cannot be defined inside a function.
*
* Archs which need weak percpu definitions should define
* ARCH_NEEDS_WEAK_PER_CPU in asm/percpu.h when necessary.

即,__attribute__((weak)) 不是用于符号解析,而是用于代码生成副作用。有一个 #else 条件,其中 weak 并发症不受干扰。

现在简要回答您的问题,

For Goal #1. How could it enforce scope?

staticnon-static 声明结果,

DECLARE_PER_CPU_PAGE_ALIGNED(int,foobar);
static DEFINE_PER_CPU_PAGE_ALIGNED(int,foobar);

For Goal #2, ... __pcpu_unique_##name, then how it help to ensure the uniqueness ?

多个 weak 符号不会导致错误。 __pcpu_unique_##name 不是weak 所以它被用来强制执行uniqueness 因为 weak 被用于代码生成原因。

参见 Gcc's function attributes并搜索 weak,以防 weak 的正常目的不被理解。

关于c - C中如何保证全局符号的唯一性并限制其作用域?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16291715/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com