了解glibc的源$ C $ C约定 [英] Understanding glibc source code conventions
问题描述
我一直在寻找一些来源$ 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)
-
上线22和23看起来像我明白了声明。它有
INT
的返回类型,那么函数名__ pthread_equal
和参数列表(线程1 ,线程)
。但什么是上线24的声明的pthread_t线程1;
25的pthread_t线程2;
的呢?它看起来像这些被声明为全局变量,但我不明白的目的。我已经看到了这种模式在很多文件中的NPTL目录,一直无法弄清楚为什么这样做。 -
什么是
strong_alias
?快速谷歌搜索有此被使用的例子,但我没有找到一个链接到任何文件。 -
什么是prefacing一些名字以两个下划线
__
有的一个下划线_ $ C的原因$ C>。大部分的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)
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 24pthread_t thread1;
and 25pthread_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.What is
strong_alias
? A quick Google search has examples of this being used but I did not find a link to any documentation.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.h556 /* 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
wasint
since it wasn't specified as anything else. It is unlikely that theglib
code takes advantage of that licence. Similarly, the return type ofmain()
wasint
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 thepthread_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
, andva_end
.
这篇关于了解glibc的源$ C $ C约定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!