We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 779

Summary: Const issues with SDL_putenv() ...
Product: SDL Reporter: Ryan C. Gordon <icculus>
Component: *don't know*Assignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P1    
Version: HG 2.0   
Hardware: x86   
OS: Linux   

Description Ryan C. Gordon 2009-08-11 23:53:41 UTC
Man page for putenv() on Linux says this:
   "SUSv2 removes the const from the prototype, and so does glibc 2.1.3."

Namely: it saves the string pointer, and allows you to overwrite it! (That is, apparently getenv() will return _that same pointer_ and it's legal to write directly to it to change the environment table's data.

Yeah, that's nasty.

But when SDL_putenv() isn't #define'd to use putenv() directly, it expects a const char * for the argument.

So on Ubuntu 9.10, for example, this causes a compiler warning:

   SDL_putenv("SDL_VIDEO_CENTERED=1");

"warning: deprecated conversion from string constant to ‘char*’"

Not sure what the best approach is here. I'm sure other Unixes want a const char * for putenv(), even though the standard apparently says that's wrong.

--ryan.
Comment 1 Sam Lantinga 2009-09-26 03:44:52 UTC
Yuck.

Does putenv("FOO=1") generate a warning as well?  Or does the compiler put that string into the writable data segment?
Comment 2 Ryan C. Gordon 2009-12-14 23:18:44 UTC
For the program...

#include <stdlib.h>

int main(void)
{
    char buf[10];
    char *char_ptr = buf;
    const char *const_char_ptr = char_ptr;
    putenv(buf);
    putenv(char_ptr);
    putenv(const_char_ptr);
    putenv("STRING_LITERAL=1");
    return 0;
}

... the only line it complains about is...

    putenv(const_char_ptr);

testenv.c: In function main:
testenv.c:10: warning: passing argument 1 of putenv discards qualifiers from pointer target type
/usr/include/stdlib.h:578: note: expected char * but argument is of type const char *

The string literal didn't trigger a warning, even with -Wall. Probably way too much legacy code that passes literals to things that want (char*). It DOES report the same warning with -Wwrite-strings. The manpage says this isn't part of -Wall because it's a nuisance for code with mismatched const qualifiers.

If compiled as C++...

testenv.cpp:10: error: invalid conversion from const char* to char*
testenv.cpp:10: error:   initializing argument 1 of int putenv(char*)
testenv.cpp:11: warning: deprecated conversion from string constant to char*

The string literal is a warning by default, the const_char_ptr is an error.

--ryan.
Comment 3 Ryan C. Gordon 2009-12-14 23:45:06 UTC
After heated debate via Google Talk, I'm taking this bug.   :)

--ryan.
Comment 4 Ryan C. Gordon 2009-12-15 10:01:31 UTC
After heated debate with myself, I'm leaving this alone.

Of several options, the "best" option was to just leave a warning comment and move on.

"Fixed" in svn revision #5402.

--ryan.
Comment 5 Sam Lantinga 2009-12-15 11:52:35 UTC
Let's do setenv in 1.3 and throw putenv in SDL_compat.c
Comment 6 Ryan C. Gordon 2009-12-15 22:33:04 UTC
Bumping priority on a set of bugs.

--ryan.
Comment 7 Ryan C. Gordon 2009-12-16 03:01:37 UTC
Fixed in svn revision #5416.

Sam, can you look over this patch? It turned out to be bigger than I expected for a 6am quicky-fix, and I don't have a Windows install for testing that common case at the moment in any case.

--ryan.