首页 > 解决方案 > 从函数返回的指向静态分配结构的指针究竟如何?

问题描述

在 Michael Kerrisk 的书中,我遇到了以下这样的陈述:

  • “gmtime() 和 localtime() 函数将 time_t 值转换为所谓的故障时间。故障时间放置在
    静态分配的结构中,其地址作为
    函数结果返回。
  #include <time.h> 
  struct tm *gmtime(const time_t timep );
  struct tm *localtime(const time_t * timep ); 
  /* Both return a pointer to a statically allocated broken-down time structure on
 success, or NULL on error */

所以我试图弄清楚说“指向静态分配结构的指针”是什么意思,当跟踪“time.h”文件的源代码时,我在跟踪源代码时到达了文件glibc/time/localtime.c顺序如下; https://code.woboq.org/userspace/glibc/time/gmtime.c.html

https://code.woboq.org/userspace/glibc/time/localtime.c.html#22

据我了解,gmtime()函数返回一个指向这个全局定义结构的指针,如下声明:

struct tm _tmbuf;

所以我的问题是,到目前为止,我是否正确,gmtime 只返回一个指向这个全局结构的指针?如果是这样,下一个问题是,我是否可以在共享库文件中定义全局变量?如果是的话,如何访问库文件中的那些全局变量?

标签: clinuxpointerstime

解决方案


是的,你做对了,是的,你可以做同样的事情。如果您要在自己的库中编写这样的函数,它可能如下所示:

struct tm _tmbuf;

struct tm *gmtime(const time_t *timep)
{
    struct tm *t = &_tmbuf;
    // Do some things with timep and t.
    return t;
}

但是请注意,正如所写,这不是线程安全的。如果您希望人们在线程程序中使用您的库,您需要将变量声明为 thread local;使用互斥锁、rwlock 或其他互斥机制;localtime_r或提供一个线程安全版本gmtime_r,例如用户指定用作输出的结构。

由于这些原因,通常认为这样做是不可取的,并且像 Rust 这样的语言使它变得困难,因为它很容易成为线程不安全的。


推荐阅读