在C/C++中,errno在哪里定义和分配?

4

同样的答案是:printf被声明为外部函数,我们可以调用它,那么它在哪里定义呢? - user253751
它可能被分配在线程堆栈头部的实际存储区中。它的“位置”是由操作系统/架构定义的,而且由于它必须是线程特定的,所以堆栈头似乎是操作系统放置它的显然之处。 - Martin James
1个回答

10
在链接的源代码示例中,版权超过20年,很可能C运行时库有一个变量 int errno;。头文件中的 extern int errno; 只是意味着 "这个变量存在,你会在其他地方找到它" - 也许就在实际调用你的 main 函数的代码旁边,或者类似的地方。
通常在具有线程的现代操作系统中,errno 并不严格是一个变量。
这是 Linux 中的示例,来自 glibc 的 /usr/include/bits/errno.h。
# ifndef __ASSEMBLER__

/* Function to get address of global `errno' variable.  */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));

#  if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value.  */
#   define errno (*__errno_location ())
#  endif
# endif /* !__ASSEMBLER__ */
#endif /* _ERRNO_H */

准确地说,__errno_location 的实现取决于哪个操作系统的哪个版本,但基本上是这样的:

__thread int errno;

在C ++11中,__thread是用来支持线程本地存储说明符thread_local的,它由操作系统作为某种“每个线程交换数据”的类型存储方式进行支持。确切的实现方式取决于操作系统。在x86和x86-64中,fsgs分别用于“每个CPU”和“每个线程”的存储(但它们是“相对”),我现在无法确定哪一个是哪一个。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接