предупреждение путенв с с ++ - PullRequest
0 голосов
/ 20 января 2019

Я пытаюсь использовать функцию putenv stdlib в программе, которую я компилирую с g++, включая флаги и предупреждения -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жаловаться.

Я знаю, что могу разыграть, но есть ли правильный способ использовать функцию putenv в C ++ или, если это функция C, ее следует полностью избегать?

Ответы [ 4 ]

0 голосов
/ 20 января 2019

Альтернативой является следование руководству putenv manpage , которое вы должны вместо этого использовать более современный и безопасный setenv, который не имеет этой проблемы, нилюбой из сложностей, которые возникают из этого.

0 голосов
/ 20 января 2019

Хотя std::getenv является частью стандарта C ++ (и также стандарта C, но в будущем выберите один язык, который вына самом деле программа, в которой в вашем случае C ++), функция putenv не является.

Как вы можете видеть из ссылки на POSIX для putenv аргумент имеет тип char *.

Это очень важно, и одна вещь, которая отличается между C и C ++: в C литеральная строка может быть передана функциям, ожидающим char *.В C ++ все строковые литералы константа и могут быть переданы только функциям, ожидающим const char *.

Для решения вашей проблемы вам нужно использовать непостояннуюмассив, который вы инициализируете, а затем передаете:

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

Важное примечание: массив должен быть действителен в течение всего срока службы вашей программы.Это означает, что даже после возврата функции main.

Лучшим решением (и упомянутым в комментарии) является функция setenv, которая принимает const char * в качестве аргумента (и поэтому может использоваться с литеральными строками), а также копирует аргументы, что означает, что нет проблем с областью действия и временем жизни.


Относительно строковых литералов.И в C, и в C ++ они действительно являются массивами символов.Разница в том, что в C ++ массивы постоянны.

0 голосов
/ 20 января 2019

На проблему уже указывают другие ответы.В C++ строковый литерал имеет тип const char[], в то время как в C это char[], но изменение его приведет к неопределенному поведению.

Согласно странице man :

Функция putenv () добавляет или изменяет значение переменных среды.Строка аргумента имеет форму имя = значение.Если имя еще не существует в среде, то строка добавляется в среду.Если имя существует, то значение имени в среде изменяется на значение.Строка, на которую указывает строка, становится частью окружения, поэтому ее изменение меняет окружение.

...

Таким образом, ошибочно вызывать putenv () с автоматическимпеременная в качестве аргумента, затем вернитесь из вызывающей функции, пока строка все еще является частью среды.

Вы должны быть осторожны, когда вызываете putenv с переменной автоматического хранения (например, если вывызовите его в функции, отличной от main), поскольку указатель становится частью среды.

0 голосов
/ 20 января 2019

putenv получите (не константный) char * и вы дадите const char *, компилятор недоволен и это нормально

просто сделай

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

putenv(s);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...