简体   繁体   中英

putenv warning with C++

I am trying to use putenv stdlib function in a program that I am compiling with g++ including the flags and warnings -std=c++11 and -Wall -Wextra .

The program can be as easy as the following:

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

}

but I am getting this error warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] .

As far as I understood in C++ I should declare: char const *str = but then putenv is complaining.

I know I could cast but is there a proper way to use putenv function in C++ or being it a C function it should be completely avoided?

While std::getenv is part of the C++ standard (and the C standard as well, but in the future pick one language, the one you really program in which in your case is C++), the putenv function isn't.

As you can see from the linked POSIX reference for putenv , it's argument is of type char * .

This is very important, and one thing that differs between C and C++: In C a literal string can be passed to functions expecting char * . In C++ all literal strings are constant and can only be passed to functions expecting const char * .

To solve your problem, you need to use a non-constant array that you initialize and then pass:

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

Important note: The array must be valid during the full life-time of your program. That means even after the main function returns.

A better solution (and mentioned in a comment) is the setenv function, which both takes const char * for its argument (and can therefore be used with literal strings) and also copies the arguments which means there's no problem about scope and life-time.


Regarding string literals. In both C and C++ they are really arrays of characters. The difference is that in C++ the arrays are constant.

The problem is already pointed out by other answers. In C++ a string literal is of type const char[] while in C it is char[] , but modifying it will lead to undefined behavior.

According to the man page:

The putenv() function adds or changes the value of environment variables. The argument string is of the form name=value. If name does not already exist in the environment, then string is added to the environment. If name does exist, then the value of name in the environment is changed to value. The string pointed to by string becomes part of the environment, so altering the string changes the environment.

...

Thus, it is an error is to call putenv() with an automatic variable as the argument, then return from the calling function while string is still part of the environment.

You should be careful when you call putenv with a variable of automatic storage (for example if you call it in a function other than main ) since the pointer becomes part of the environment.

一种替代方法是遵循putenv的建议,而应该使用更现代,更安全的setenv ,它不存在此问题,也不存在由此而引起的任何复杂性。

putenv get a (non const) char * and you give a const char * , the compiler is not happy and this normal

just do

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

putenv(s);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM