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

将外部变量导入本地时,`#include`和`extern`之间有什么区别?,c,C,在使用errno时,我曾经读到 重要的是要包含errno.h,而不是提供您自己的 extern int errno,因为errno是在线程安全的环境中实现的 不仅仅是一个简单的全局int的方式 线程安全的方式如何影响#include和extern之间的差异 在POSIX.1中,errno被定义为外部全局变量。但是这个 定义在多线程环境中是不可接受的,因为 使用会导致不确定的结果。问题是有两三个 更多线程可能会遇到错误,所有这些都会导致相同的errno被删除 设置在这些情况下,线程可能会检查err

在使用
errno
时,我曾经读到

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

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

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

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

某些函数可能在通过符号errno访问的变量中提供错误号。符号errno是通过包含 标题,如C标准所规定。。。每根线 对于一个过程,errno的值不应受到功能的影响 其他线程对errno的调用或分配

此外,所有POSIX.1c函数都避免使用errno,而是, 将错误号直接作为函数返回值返回,带有 返回值为零,表示未检测到错误。这 事实上,所有新产品都在POSIX范围内遵循该战略 功能

重要的不是外部对包括

errno在标头中定义为

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

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

引用的文档警告您不要假设
errno
实现为

extern int errno;
标题中,仅此而已

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


如果你真的对细节感兴趣,在编辑器中打开你的
errno.h
,看看。但是,您需要记住,在其他系统上的实现可能(并且通常会)是不同的。

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

,我想说的是,重要的是所有线程之间没有共享一个
errno
<代码>\u errno根据调用的线程返回不同的地址。@SteveJessop-是的,对不起,我写的是胡言乱语!