How to restructure old C initialisation of char* to avoid compiler warnings

T

tropos

For my sins, I'm maintaining some old C code which is migrated to C++.
Dozens of lines of it looks like this:

char *cfd_THE_ts_result_sql= "select TRADE_DATE , VALUE , "
" from ("
" select to_char(TRADE_DATE,'yyyymmdd') trade_date ,
THEORETICAL_HIGH_VALUE"
" from %s "
" where trade_date = (select max(trade_date ) from %s where "
<snip>
;


The Solaris native C++ compiler complains a lot, saying "Warning:
String literal converted to char* in initialization." Even if I
convert the "char *" to "const char *", a lot of the continuation lines
get that warning. I'd like to get rid of the warnings.

Being a nice C++ coder, I find a line like

char * s1 = "something " "and something else" "and more" ;

pretty wierd. Is this even legitimate C?
Is there any way to concatenate C strings, upon initialisation of a
char *, that won't reap a warning?

Thanks

Tropos
 
G

Greg

tropos said:
For my sins, I'm maintaining some old C code which is migrated to C++.
Dozens of lines of it looks like this:

char *cfd_THE_ts_result_sql= "select TRADE_DATE , VALUE , "
" from ("
" select to_char(TRADE_DATE,'yyyymmdd') trade_date ,
THEORETICAL_HIGH_VALUE"
" from %s "
" where trade_date = (select max(trade_date ) from %s where "
<snip>
;


The Solaris native C++ compiler complains a lot, saying "Warning:
String literal converted to char* in initialization." Even if I
convert the "char *" to "const char *", a lot of the continuation lines
get that warning. I'd like to get rid of the warnings.

Being a nice C++ coder, I find a line like

char * s1 = "something " "and something else" "and more" ;

pretty wierd. Is this even legitimate C?
Is there any way to concatenate C strings, upon initialisation of a
char *, that won't reap a warning?

Change the char * declarations to implicitly-sized character arrays. In
other words, replace:

char * s1 = "something " "and something else" "and more" ;

with

char s1[] = "something " "and something else" "and more" ;

That should eliminate the warnings because an array declaration
effectively allocates writable storage. In other words, a char array is
suitable for initialization by a constant string literal, whereas a
char pointer (with no allocated, writable storage of its own) is not.

Greg
 
E

Earl Purple

Greg said:
Change the char * declarations to implicitly-sized character arrays. In
other words, replace:

char * s1 = "something " "and something else" "and more" ;

with

char s1[] = "something " "and something else" "and more" ;

That should eliminate the warnings because an array declaration
effectively allocates writable storage. In other words, a char array is
suitable for initialization by a constant string literal, whereas a
char pointer (with no allocated, writable storage of its own) is not.

Greg

Beware though what happens afterwards. If you are returning these
pointers from functions, for example, you will now be returning local
stack.

I don't know why you are getting the warnings by putting const in. That
should fix it.
The concatenations are perfectly valid in C++ too and have nothing to
do with the warnings. Such a trick with concatenations is useful when
you have a long literal string that you want to break over lines.
 
G

Greg

Earl said:
Greg said:
Change the char * declarations to implicitly-sized character arrays. In
other words, replace:

char * s1 = "something " "and something else" "and more" ;

with

char s1[] = "something " "and something else" "and more" ;

That should eliminate the warnings because an array declaration
effectively allocates writable storage. In other words, a char array is
suitable for initialization by a constant string literal, whereas a
char pointer (with no allocated, writable storage of its own) is not.

Greg

Beware though what happens afterwards. If you are returning these
pointers from functions, for example, you will now be returning local
stack.

That is a good point, I had assumed that these were global string
declarations.
I don't know why you are getting the warnings by putting const in. That
should fix it.
The concatenations are perfectly valid in C++ too and have nothing to
do with the warnings. Such a trick with concatenations is useful when
you have a long literal string that you want to break over lines.

I believe the issue with the concatenation is that only "adjacent"
string literals are to be combined. Apparently strings literals not on
the same line should not be considered adjacent to each other.

Nonetheless, it seems that most, if not all, C++ compilers do
concatenate strings on separate lines, but at least some have
deprecated the feature (hence the warnings). At any rate, adding a
backslash to the end of each line that evokes a warning will combine
the line with the one following - essentially creating one very long
line from the compiler's point of view.

Greg
 
F

Frederick Gotham

tropos posted:
Being a nice C++ coder, I find a line like

char * s1 = "something " "and something else" "and more" ;

pretty wierd.


It's used all the time. Two string literals place side by side become one;
the initialisation above is equivalent to:

char *s1 = "something and something else and more";

Is this even legitimate C?


Legal C89. Legal C99. Legal C++.

Is there any way to concatenate C strings, upon initialisation of a
char *, that won't reap a warning?


Just disable the warning. Depending on how "clever" the code is, you might
run into problems if you change the pointers to "pointer to const".
 
J

Jack Klein

For my sins, I'm maintaining some old C code which is migrated to C++.
Dozens of lines of it looks like this:

char *cfd_THE_ts_result_sql= "select TRADE_DATE , VALUE , "
" from ("
" select to_char(TRADE_DATE,'yyyymmdd') trade_date ,
THEORETICAL_HIGH_VALUE"
" from %s "
" where trade_date = (select max(trade_date ) from %s where "
<snip>
;


The Solaris native C++ compiler complains a lot, saying "Warning:
String literal converted to char* in initialization." Even if I
convert the "char *" to "const char *", a lot of the continuation lines
get that warning. I'd like to get rid of the warnings.

Being a nice C++ coder, I find a line like

char * s1 = "something " "and something else" "and more" ;

pretty wierd. Is this even legitimate C?
Is there any way to concatenate C strings, upon initialisation of a
char *, that won't reap a warning?

Thanks

Tropos

If your C++ compiler issues that message on this:

const char *c1 = "Hello, " "World";

....it is broken.

If your C++ compiler does not issue that message on the above, but it
does issue that message on this:

const char *c1 = "H"
"e"
"l"
"l"
"o"
","
" "
"W"
"o"
"r"
"l"
"d";

....then it is still broken.

According to the standard, both of these should appear to the
"compiler" as:

const char *c1 = "Hello, World"

In translation phase 6, adjacent string literals are concatenated. It
isn't until translation phase 7 that preprocessing tokens, which
include keywords like "const" and "char", are analyzed syntactically
and semantically.

So if you modify the code to look like the first or second examples,
and you get that message from the compiler, your compiler is
non-conforming. Are you sure there isn't something different about
the continuation lines that "get that warning" even after you change
the type of the pointer to const char *?

Why not copy and post one that generates the warning and one that does
not?
 
G

Gavin Deane

Greg said:
I believe the issue with the concatenation is that only "adjacent"
string literals are to be combined. Apparently strings literals not on
the same line should not be considered adjacent to each other.

Who said that?

#include <string>
int main()
{
std::string s = "this is split"
"over two lines";
}

is perfectly correct. The two string literals are adjacent and are
concatenated.

Gavin Deane
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top