将extern变量导入本地时,`#include`和`extern`有什么区别?

时间:2012-03-31 14:32:36

标签: c

在使用errno时,我曾读过

字样
  

重要的是要包含 errno.h ,而不是提供自己的    extern int errno ,因为 errno 是在线程安全中实现的   这种方式不仅仅是一个简单的全球 int

线程安全方式如何影响#includeextern之间的差异?

4 个答案:

答案 0 :(得分:4)

重要的不是extern vs #include

errno在标题中定义为

int*    _errno(void);
#define errno       (*_errno())

每个线程在自己的地址空间中都有自己的错误

答案 1 :(得分:3)

  

在POSIX.1中,errno被定义为外部全局变量。但是这个   定义在多线程环境中是不可接受的,因为它   使用会导致不确定的结果。问题是两个还是   更多线程可能会遇到错误,所有错误都会导致相同的错误   组。在这种情况下,线程可能最终检查错误   在它已经被另一个线程更新之后。

     

为了规避由此产生的不确定性,POSIX.1c重新定义了错误   作为可以访问每线程错误号的服务,如下所示   (ISO / IEC 9945:1-1996,§2.4):

     

某些函数可能会在通过符号errno访问的变量中提供错误编号。符号errno的定义包括   标题,由C标准指定...对于每个线程   在一个过程中,errno的值不受功能的影响   其他线程对errno的调用或赋值。

     

此外,所有POSIX.1c函数都避免使用errno,而是   直接返回错误号作为函数返回值,用a   返回值为零表示未检测到错误。这个   事实上,策略是在POSIX范围内对所有新策略进行跟踪   功能

http://www.unix.org/whitepapers/reentrant.html

答案 2 :(得分:2)

引用的文档警告您,您不应该假设 errno被实现为

extern int errno;
<{1>}标题中的

,就是全部。

显然,包含文件中可能包含<errno.h>以外的内容;在这种情况下,实现者采取预防措施使extern以线程安全的方式运行,但这是一个不必要的细节。真正必须知道的是你必须包括errno

如果您对细节非常好奇,请​​在编辑器中调出errno.h,然后查看。但是,您需要记住,其他系统上的实现可能(通常也会)不同。

答案 3 :(得分:0)

至少在mysystem中,它被定义为#define errno (*__error()),即它被计算为error,它返回指向正确结果的指针。通过这种方式,您可以实现线程安全errno