I'm using some C functions in my C++ environment. And I get the following warnings because C++ doesn't allow assigning string literal to char *
type.
C++11 does not allow conversion from string literal to char *
My Code:
void sys_vgui(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
//do something
va_end(ap);
}
void open(t_buf *x)
{
sys_vgui("wm deiconify .x%lx\n", x);
sys_vgui("raise .x%lx\n", x);
sys_vgui("focus .x%lx.text\n", x);
}
And I could remove these warnings by const casting the string literals as the following.
sys_vgui(const_cast<char *>("wm deiconify .x%lx\n"), x);
sys_vgui(const_cast<char *>("raise .x%lx\n"), x);
sys_vgui(const_cast<char *>("focus .x%lx.text\n"), x);
But I'm not sure if it's really safe as I've seen many people saying not to directly cast string literal to char *
.
So I came up with the following which seems like a safer solution.
char str1[] = "wm deiconify .x%lx\n";
sys_vgui(str1, x);
char str2[] = "raise .x%lx\n";
sys_vgui(str2, x);
char str3[] = "focus .x%lx.text\n";
sys_vgui(str3, x);
But it makes my code dirty and harder to maintain as I have to create multiple variables using different names(e.g. str1, str2, str3...) whenever I use the function.
So my questions are:
1) Is it really not safe to use const_cast<char *>
in my case?
2) Any solution to write a clean code using char
arrays without having to create multiple variables using different names?
It is safe as long as sys_vgui
does not modify the string, which presumably it doesn't because modifying a string literal has undefined behavior in C, const
or not. So if you have something like
sys_vgui("wm deiconify .x%lx\n", x);
in C, then the C++ version with const_cast
is just as safe.
However, to de-uglify the C++ code, I'd probably write a wrapper function:
template<typename ...Ts>
void xsys_vgui(const char *fmt, Ts ...args) {
sys_vgui(const_cast<char *>(fmt), args ...);
}
Now
xsys_vgui("wm deiconify .x%lx\n", x);
should "just work" in C++.