| 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 | ||
Yuck.
Does putenv("FOO=1") generate a warning as well? Or does the compiler put that string into the writable data segment?
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.
After heated debate via Google Talk, I'm taking this bug. :) --ryan. 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. Let's do setenv in 1.3 and throw putenv in SDL_compat.c Bumping priority on a set of bugs. --ryan. 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. |
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.