【问题标题】:Where errno is defined and allocated in C/C++?errno 在 C/C++ 中在哪里定义和分配?
【发布时间】:2015-11-29 23:22:24
【问题描述】:

我在这里查看 errno.h 的源代码: http://unix.superglobalmegacorp.com/Net2/newsrc/sys/errno.h.html

说明errno被声明为extern,我们在使用errno的时候可以直接给它赋值。就是说errno是在别的地方定义和分配的,到底是在哪里定义的?

【问题讨论】:

  • 相同的答案:printf 被声明(隐式为 extern),我们可以调用它,那么它在哪里定义?
  • 它可能像在实际存储中一样被分配在线程堆栈头中。它的“位置”是操作系统/架构定义的,因为它必须是特定于线程的,所以堆栈头似乎是操作系统放置它的明显位置。

标签: c++ c linux errno


【解决方案1】:

在 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;

其中__thread 转换C++11 thread_local 存储说明符,并被操作系统支持为某种“每线程交换数据”类型的存储。确切的实现方式再次取决于操作系统。在 x86 和 x86-64 中,fsgs 用于“每个 CPU”和“每个线程”存储(但它们是“对立的”,我现在不太记得哪个是哪个)

【讨论】:

    猜你喜欢
    • 2011-04-05
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 2013-09-13
    相关资源
    最近更新 更多