了解glibc的源$ C ​​$ C约定 [英] Understanding glibc source code conventions

查看:145
本文介绍了了解glibc的源$ C ​​$ C约定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找一些来源$ C ​​$ c代表的glibc,特别是NPTL code,我发现它有点难以理解,因为它似乎有约定,我'不熟悉,

例如我一直在寻找一个非常小的文件<一个href=\"http://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_equal.c;h=86279e77b7fda14da9c4c34730703739b4b17d7b;hb=HEAD\">pthread_equal.c而且有几件事情,我对问题:

  22 INT
23 __pthread_equal(线程1,线程2)
24的pthread_t线程1;
25的pthread_t线程2;
26 {
27回线程1 ==线程2;
28}
29 strong_alias(__pthread_equal,pthread_equal)


  1. 上线22和23看起来像我明白了声明。它有 INT 的返回类型,那么函数名 __ pthread_equal 和参数列表(线程1 ,线程)。但什么是上线24 的声明的pthread_t线程1; 25 的pthread_t线程2; 的呢?它看起来像这些被声明为全局变量,但我不明白的目的。我已经看到了这种模式在很多文件中的NPTL目录,一直无法弄清楚为什么这样做。


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


  3. 什么是prefacing一些名字以两个下划线 __ 有的一个下划线 _ 。大部分的code我已经看到了使用两个下划线,但我想我已经看到了一些地方使用了一个下划线。例如,在<一href=\"http://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthreadP.h;h=68c690e88e9f5c350ac3778e9795f777f633e43b;hb=HEAD#l556\">pthreadP.h

      556 / *旧的清理接口,libc.so.仍在使用* /
    557的extern无效_pthread_cleanup_push(结构_pthread_cleanup_buffer *缓冲区,
    558无效(*例程)(无效*),无效* ARG);
    559的extern无效_pthread_cleanup_pop(结构_pthread_cleanup_buffer *缓冲区,
    560 INT执行);
    561的extern无效_pthread_cleanup_push_defer(结构_pthread_cleanup_buffer *缓冲区,
    562无效(*例程)(无效*),无效* ARG);
    563的extern无效_pthread_cleanup_pop_restore(结构_pthread_cleanup_buffer *缓冲区,
    564 INT执行);


诚然是code是一个评论,说:旧的清理接口,但无论哪种方式,我很好奇的差异,为什么有时候有一个下划线被使用,有时使用两个下划线pfaced $ P $。

有关这些问题的任何信息都是AP preciated。


解决方案

该功能无需C89兼容的编译器写的;它会与老的编译器工作了。这是一个非原型函数定义

  INT / *返回类型* /
功能(ARG1,ARG2)/ *函数名和参数名称(但没有种)* /
    INT ARG1; / * ARG1类型* /
    字符* ARG2; / * ARG2的类型* /
{
    / *函数体* /
}

注意,参数的定义,不必在同一序列中的功能线(我不得不code从这个转换'K&安培; R标记为原型标记他们在那里了顺序!)。还要注意,它曾经是可以简单地写:

 主(ARGC,ARGV)
    焦炭** argv的;
{
    ...
}

ARGC 隐含类型是 INT ,因为它没有被指定为别的。这是不太可能的巧舌如簧 code采用该许可证的优势。同样,返回类型的main() INT ,因为没有其他类型的给予。

strong_alias 有关,隐藏和共享库中暴露的符号。我没有使用过,所以我不知道所有的后果,但我相信它意味着 __ pthread_equal()的另一个名字为 pthread_equal()功能。


__ pthread_equal()名字背后的推理的一个部分是开始以下划线后跟一个大写字母名称或另一个下划线保留到实现C标准。名称,如pthread_equal()是用户的名字空间根据C标准。

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


  

7.1.3保留标识符


  
  

每个标题声明或定义在其相关的上市节所有标识符,并
  可选声明或定义在其相关联的未来图书馆方向上市标识符
  款和它们总是保留要么为任何用途或用作文件识别符
  范围标识符。


  
  

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


  
  

- 以下划线开头的所有标识符总是保留用作标识符
  在这两个普通和标记的名称空间文件范围。


  
  

- 任一下列条款的每一个宏名(包括未来图书馆
  方向)被保留用于如果任何相关标头包括按照指定;
  除非另有明确规定(见7.1.4)。


  
  

- 在任何以下小节的外部连接(包括所有的标识符
  未来图书馆方向)总是保留用于与外部标识符
  联动。 154)


  
  

- 在任何以下小节上市文件范围内每个标识符(包括
  未来图书馆方向)被保留用于为宏名称和与标识符
  如果任何相关报头被包括在相同的名称空间的文件范围。


  
  

没有其它标识符是保留。如果程序声明或在一个限定的标识符
  上下文中它被保留(比其它由7.1.4所允许),或限定一个保留
  标识为宏名,行为是不确定的。


  
  

154)保留标识符有外部链接列表中包括错误号 math_errhandling
  的setjmp va_end用来


I've been looking at some of the source code for glibc, in particular the nptl code, and I've found it a little bit hard to understand since it seems to have conventions that I'm not familiar with.

For example I was looking at a very small file pthread_equal.c and there are a few things that I had questions about:

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. The declaration on lines 22 and 23 looks like something I understand. It has a return type of int then the function name __pthread_equal and the parameter list (thread1, thread2). But what are the declarations on lines 24 pthread_t thread1; and 25 pthread_t thread2; for? It looks like these are being declared as global variables but I don't understand the purpose. I've seen this pattern in many files in the nptl directory and haven't been able to figure out why this is done.

  2. What is strong_alias? A quick Google search has examples of this being used but I did not find a link to any documentation.

  3. What is the reason for prefacing some names with two underscores __ and some with one underscore _. Most of the code I've seen uses the two underscores but I think I have seen some places where one underscore is used. For instance in 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);
    

Admittedly that code is prefaced with a comment that says "old cleanup interfaces" but either way I'm curious about the difference and why sometimes one underscore is used and sometimes two underscores are used.

Any information regarding these questions is appreciated.

解决方案

The function is written without requiring a C89 compliant compiler; it will work with older compilers too. That is a non-prototype function definition.

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 */
}

Note that the definitions of the arguments do not have to be in the same sequence as in the function line (I've had to convert code from this 'K&R' notation to prototype notation where they were out of order!). Also note that it used to be possible to simply write:

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

The implied type for argc was int since it wasn't specified as anything else. It is unlikely that the glib code takes advantage of that licence. Similarly, the return type of main() was int because no other type was given.

The strong_alias is related to hiding and exposing symbols in shared libraries. I've not used it, so I'm not sure of all the ramifications, but I believe it means that __pthread_equal() is another name for the pthread_equal() function.


One part of the reasoning behind the __pthread_equal() name is that names starting with an underscore followed by an upper-case letter or another underscore are 'reserved to the implementation' by the C Standard. Names such as 'pthread_equal()' are in the users' name space according to the C standard.

ISO/IEC 9899:1990 (the C99 standard) says:

7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).

— All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154)

— Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

154) The list of reserved identifiers with external linkage includes errno, math_errhandling, setjmp, and va_end.

这篇关于了解glibc的源$ C ​​$ C约定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆