代码之家  ›  专栏  ›  技术社区  ›  Don Wakefield

在静态初始值设定项中使用getenv()安全吗,即在main()之前?

  •  12
  • Don Wakefield  · 技术社区  · 16 年前

    我进去看了看 Stevens ,在 Posix Programmer's Guide ,我能找到的最好的

    称为 环境 此数组由外部变量指向 environ

    extern char **environ;

    包围

    -“外部”变量 被用作入口点 getenv()

    - 事实上 在静态初始值设定项中。

    但我无法保证 位于所有其他静态初始化代码之前。我是不是想得太多了?

    使现代化

    在…上 平台(AMD Opteron、Redhat 4、GCC 3.2.3)、设置 表明 包围 之前 我的静态初始值设定项称为。知道这是件好事;谢谢,@codelogic。但这并不一定是我在所有平台上都能得到的结果。

    此外,虽然我直觉上同意@ChrisW对C/C++运行库行为的看法,但这只是我基于经验的直觉。所以任何人都可以引用某个地方的话来保证这一点 包围

    3 回复  |  直到 9 年前
        1
  •  8
  •   codelogic    16 年前

    我认为您可以使用LD_DEBUG set运行程序,以查看确切的顺序:

    LD_DEBUG=all <myprogram>
    

    如果您查看运行时链接器(glibc 2.7)的源代码,特别是在文件中:

    • sysdeps/i386/init first.c
    • sysdeps/i386/elf/start.S

    __ 在调用任何全局构造函数(init函数)之前设置。您可以从实际入口点(start.S)开始跟踪执行。正如你引用史蒂文斯的话 “进程开始时,称为Environment的字符串数组可用” ,表明环境分配发生在流程初始化的最开始。这一点得到了链接器代码的支持,链接器代码也起到了同样的作用,应该可以让您充分安心:-)

    编辑2: 还值得一提的是,environ设置得足够早,甚至运行时链接器都可以查询它以确定是否要详细输出(LD_DEBUG)。

        2
  •  4
  •   Tall Jeff    16 年前

    同时,我不知道有一个特定的需求限制哪些运行时库函数可以从静态初始值设定项调用。而且,更重要的是,如果您不能从运行时bug访问环境,那么(对我来说)它会感觉像一个运行时bug。

    在这个基础上,我认为我认为这会起作用,这是一个安全的假设,目前的数据点似乎支持这条推理路线。

        3
  •  1
  •   ChrisW    16 年前

    根据我的经验,C运行时库是在运行时调用静态变量的初始值设定项之前初始化的(因此初始值设定项可以调用C运行时库函数)。