invalid conversion from 'const char*' to 'char*'

I thought string.c_str() did convert to char*? Where did the const come from? Also how would you ultimately send a std::string to putenv() then?

1
2
3
4
5
6
7
#include <iostream>

int main(){
    std::string win_center = "SDL_VIDEO_CENTERED=1";
    //putenv(win_center);
    putenv(win_center.c_str());
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
test4.cpp: In function 'int main()':
test4.cpp:7:29: error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
     putenv(win_center.c_str());
                             ^
In file included from /usr/include/c++/4.8.2/cstdlib:72:0,
                 from /usr/include/c++/4.8.2/ext/string_conversions.h:41,
                 from /usr/include/c++/4.8.2/bits/basic_string.h:2815,
                 from /usr/include/c++/4.8.2/string:52,
                 from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
                 from /usr/include/c++/4.8.2/bits/ios_base.h:41,
                 from /usr/include/c++/4.8.2/ios:42,
                 from /usr/include/c++/4.8.2/ostream:38,
                 from /usr/include/c++/4.8.2/iostream:39,
                 from test4.cpp:2:
/usr/include/stdlib.h:578:12: error:   initializing argument 1 of 'int putenv(char*)' [-fpermissive]
 extern int putenv (char *__string) __THROW __nonnull ((1));
Last edited on
after googling this, i figure i need this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

int main(){
    std::string win_center = "SDL_VIDEO_CENTERED=1";
    //putenv(win_center);
    //putenv(win_center.c_str());
    
    char* win_center_char = new char[win_center.size() + 1];
    std::copy(win_center.begin(), win_center.end(), win_center_char);
    win_center_char[win_center.size()] = '\0'; 
    
    putenv(win_center_char);
    delete[] win_center_char;
}

but this does nt make any sense to me whatsoever as to why

I also found:
putenv(&win_center[0]);
Last edited on
http://www.cplusplus.com/reference/string/string/c_str/

std::string:c_str() return a constant c-string (const char*). You cannot pass a constant to a function that accepts a non-constant reference or pointer (know that it doesn't appear to be that simple, looking into it right now):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <string>

void foo(int &a_ref) //we can modify the argument passed to foo
{                //which means that the caller's version of a can be modified
}

void bar(char *c_ptr)
{
}

int main()
{
    const int a = -1;
    //foo(a); // foo has access to and is able to change a, which is constant
    foo(const_cast<int &>(a)); // okay, it isn't as simple as I suggested earlier
    std::string s = "ER MER GERD";
    bar(s.c_str()); // error, passing const char * to a non-constant pointer
    bar(const_cast<char *>(s.c_str())); // okay I guess
}


So, in your case, putenv accepts a non-constant c-string, but you try to pass a constant to it which is invalid.

Also, the internet seems to think that putenv may be deprecated. It appears that if you use _putenv it should work with c_str() (as it accepts a const char* as in argument):
http://msdn.microsoft.com/en-us/library/ms235321.aspx
http://msdn.microsoft.com/en-us/library/83zh4e6k.aspx

Not sure if that clears anything up or just makes it even more confusing...
yeah that does make sense. thanks.

const_cast<char *>(s.c_str())

I did come across this as well, but the notes said the following regarding using const_cast:
this is not safe std::string implement reference counting and it may change the value of other strings as well.


It appears the best solution suggested throughout searching is wrapping the initial post in a class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <cstring>

class DeepString{
        DeepString(const DeepString& other);
        DeepString& operator=(const DeepString& other);
        char* internal_; 
    public:
        explicit DeepString( const std::string& toCopy): 
            internal_(new char[toCopy.size()+1]) 
        {
            std::strcpy(internal_,toCopy.c_str());
        }
        ~DeepString(){ 
            delete[] internal_; 
        }
        char* str() const{ 
            return internal_;
        }
        const char* c_str()  const{
            return internal_;
        }
};

int main(){
    DeepString deep("SDL_VIDEO_CENTERED=1");
    putenv(deep.str());
    //putenv(win_center.c_str());
    

}


Also, the internet seems to think that putenv may be deprecated. It appears that if you use _putenv it should work with c_str() (as it accepts a const char* as in argument):
http://msdn.microsoft.com/en-us/library/ms235321.aspx
http://msdn.microsoft.com/en-us/library/83zh4e6k.aspx

That is the only place i found that said it was depreciated. _putenv is not available in linux. Im not sure how much i would trust something said that only comes from microsoft anyways.
I was looking for a well portable solution
Last edited on
Topic archived. No new replies allowed.