了解glibc源代码约定

时间:2012-03-14 02:38:25

标签: c pthreads libc

我一直在研究glibc的一些源代码,特别是nptl代码,我发现它有点难以理解,因为它似乎有我不熟悉的约定。 / p>

例如,我正在查看一个非常小的文件pthread_equal.c,我有一些问题:

22 int
23 __pthread_equal (thread1, thread2)
24      pthread_t thread1;
25      pthread_t thread2;
26 {
27   return thread1 == thread2;
28 }
29 strong_alias (__pthread_equal, pthread_equal)
  1. 第22和23行的声明看起来像我理解的东西。它的返回类型为int,然后是函数名__pthread_equal和参数列表(thread1, thread2)。但第24行pthread_t thread1;和25 pthread_t thread2;的声明是什么?看起来这些被声明为全局变量,但我不明白其目的。我在nptl目录中的许多文件中都看到了这种模式,并且无法弄清楚为什么会这样做。

  2. 什么是strong_alias?一个快速的谷歌搜索有使用这个的例子,但我没有找到任何文档的链接。

  3. 使用两个下划线__为某些名称添加前缀的原因是什么,有些下划线为_。我见过的大多数代码使用了两个下划线,但我想我已经看到了一些使用下划线的地方。例如在pthreadP.h

    556 /* Old cleanup interfaces, still used in libc.so.  */
    557 extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer,
    558                                    void (*routine) (void *), void *arg);
    559 extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer,
    560                                   int execute);
    561 extern void _pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer,
    562                                          void (*routine) (void *), void *arg);
    563 extern void _pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer,
    564                                           int execute);
    
  4. 不可否认,代码前面带有一个注释,上面写着“旧的清理界面”,但无论哪种方式,我都对这种差异感到好奇,为什么有时会使用一个下划线,有时会使用两个下划线。

    有关这些问题的任何信息都表示赞赏。

2 个答案:

答案 0 :(得分:9)

编写该函数时无需符合C89标准的编译器;它也适用于较旧的编译器。这是一个非原型函数定义。

int   /* Return type */
function(arg1, arg2)    /* Function name and argument names (but no types) */
    int arg1;    /* Type of arg1 */
    char *arg2;  /* Type of arg2 */
{
    /* Body of function */
}

请注意,参数的定义不必与函数行中的序列相同(我必须将代码从此'K& R'表示法转换为原型表示法,而不是它们出现故障! )。另请注意,以前可以简单地写一下:

main(argc, argv)
    char **argv;
{
    ...
}

argc的隐含类型为int,因为它未被指定为其他任何内容。 glib代码不太可能利用该许可证。同样,main()的返回类型为int,因为没有给出其他类型。

strong_alias与隐藏和公开共享库中的符号有关。我没有使用它,所以我不确定所有后果,但我认为这意味着__pthread_equal()pthread_equal()函数的另一个名称。


__pthread_equal()名称背后的推理的一部分是,以下划线开头,后跟大写字母或另一个下划线的名称由C标准“保留给实现”。根据C标准,诸如'pthread_equal()'之类的名称位于用户的名称空间中。

ISO / IEC 9899:1990(C99标准)说:

  

7.1.3保留标识符

     

每个标头声明或定义其相关子条款中列出的所有标识符,以及   可选地声明或定义其关联的未来库方向中列出的标识符   子条款和标识符,它们总是保留用于任何用途或用作文件   范围标识符。

     

- 所有以下划线和大写字母或其他字母开头的标识符   下划线总是保留用于任何用途。

     

- 所有以下划线开头的标识符始终保留用作标识符   在普通名称和标签名称空间中都有文件范围。

     

- 以下任何子条款中的每个宏名称(包括未来的库   如果包含任何相关标题,则保留指定用途;   除非另有明确说明(见7.1.4)。

     

- 以下任何子条款中包含外部链接的所有标识符(包括   未来的图书馆方向)始终保留用作外部标识符   键。 154)

     

- 具有文件范围的每个标识符在以下任何子条款中列出(包括   未来的图书馆方向)保留用作宏名称和标识符   如果包含任何相关标头,则文件范围在同一名称空间中。

     

不保留其他标识符。如果程序声明或定义了一个标识符   保留的上下文(7.1.4允许的除外),或定义保留的上下文   标识符作为宏名称,行为未定义。

     

154)包含外部链接的保留标识符列表包括errnomath_errhandling,   setjmpva_end

答案 1 :(得分:2)

  1. 旧写作。
  2. 确保__pthread_equalpthread_equal的类型相同。
  3. 区分变量名称,并区分核心区域和用户区域。