【问题标题】:putenv warning with C++使用 C++ 的 putenv 警告
【发布时间】:2019-06-14 05:20:03
【问题描述】:

我正在尝试在使用g++ 编译的程序中使用putenv stdlib 函数,包括标志和警告-std=c++11-Wall -Wextra

程序可以像下面这样简单:

#include<stdlib.h>
#include<iostream>
int main(int argc, char *argv[])
{
    putenv("LD_LIBRARY_PATH=../Desktop/lib");
    std::cout<<"hello\n";
    return 0;

}

但我收到此错误warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

据我在 C++ 中的理解,我应该声明:char const *str = 但随后 putenv 正在抱怨。

我知道我可以强制转换,但有没有正确的方法在 C++ 中使用 putenv 函数,或者它是一个应该完全避免的 C 函数?

【问题讨论】:

    标签: c++ c environment-variables


    【解决方案1】:

    putenv 得到一个(非 const)char * 而你给了一个const char *,编译器不高兴,这很正常

    只是做

    char s[] = "LD_LIBRARY_PATH =../Desktop/lib";
    
    putenv(s);
    

    【讨论】:

      【解决方案2】:

      虽然std::getenv 是 C++ 标准(以及 C 标准)的一部分,但在未来选择 一种 语言,您真正使用的编程语言在你的情况下是 C++),putenv 函数不是。

      putenv 的链接 POSIX 参考中可以看出,它的参数类型为 char *

      这是非常重要的,也是 C 和 C++ 之间的不同之处:在 C 中,可以将文字字符串传递给期望 char * 的函数。在 C++ 中,所有文字字符串都是常量,并且只能传递给期望 const char * 的函数。

      要解决你的问题,你需要使用一个你初始化然后传递的非常量数组:

      char env[] = "LD_LIBRARY_PATH=../Desktop/lib";
      putenv(env);
      

      重要提示:数组必须在程序的整个生命周期内有效。这意味着即使在 main 函数返回之后。

      一个更好的解决方案(并在评论中提到)是 setenv 函数,它既采用 const char * 作为其参数(因此可以与文字字符串一起使用)并且还复制参数,这意味着没有问题范围和生命周期。


      关于字符串文字。在 C 和 C++ 中,它们实际上是字符数组。不同之处在于,在 C++ 中,数组是常量。

      【讨论】:

      • 没有像 C++ 中的putenv
      • 只有旧的 C 版本,没有接受 const char *std::string 等的“新”版本
      • @FrancescoBoi C++ 标准没有指定putenv 函数。这是一个操作系统特定的功能。
      • @bruno: Sure there is
      • @Someprogrammerdude 让自动变量超出范围是错误的。您无法安全地将putenv() 与任何自动变量一起使用。当程序从main() 返回时,即使是main() 中的自动变量也会超出范围——但程序还没有完成,尤其是在C++ 中。 C++ 析构函数将在 main() 返回后运行,以及在 atexit() 注册的任何函数。
      【解决方案3】:

      其他答案已经指出了问题。在C++ 中,字符串文字的类型为const char[],而在C 中为char[],但修改它会导致未定义的行为。

      根据man页面:

      putenv() 函数增加或改变环境的值 变量。参数字符串的格式为 name=value。如果名字 环境中不存在,则将字符串添加到 环境。如果 name 确实存在,则 name 中的值 环境改变为价值。字符串指向的字符串 成为环境的一部分,因此更改字符串会更改 环境。

      ...

      因此,使用 putenv() 调用是错误的 自动变量作为参数,然后从调用返回 函数,而字符串仍然是环境的一部分。

      当您使用自动存储变量调用putenv 时(例如,如果您在main 以外的函数中调用它),您应该小心,因为指针会成为环境的一部分。

      【讨论】:

        【解决方案4】:

        另一种方法是遵循the putenv manpage 的建议,您应该改用更现代和更安全的setenv,它没有这个问题,也没有任何由此产生的复杂性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-06-12
          • 1970-01-01
          • 2011-02-03
          • 2022-01-09
          • 1970-01-01
          • 1970-01-01
          • 2012-05-16
          相关资源
          最近更新 更多