Lieuwe
Lieuwe

Reputation: 1842

Passing a const char* to foo(char*)

Whilst going through some c++ code as part of a PCI DSS certification review I came across the following:

I have a method in some library we use and one of its parameters is a char *, lets say this is

void foo(char* arg);

The point in the code where it calls this method looked like:

char mystring[256];
strcpy(mystring, "some value");
....
foo(mystring);

as part of the review we are getting rid of any strcpy calls (although in this example it is a bit trivial as the "some value" clearly fits in mystring)

So we get:

char mystring[256];
strncpy(mystring, "some value", sizeof(mystring));
mystring[sizeof(mystring)-1] = '\0';
....
foo(mystring);

This because I thought

foo("some value")

would pass a const char *

To my surprise however, the compiler (gcc 4) is quite happy with this. It doesn't even give any warnings when I add -Wall or -Wcast-qual

My question is this: can I in this case safely call foo("some value") when I don't know what foo is actually doing (if anything) to its argument?

Upvotes: 1

Views: 1543

Answers (3)

Mike DeSimone
Mike DeSimone

Reputation: 42805

BTW, you're using strncpy wrong. The size parameter should be the size of the destination buffer minus one:

char mystring[256];
strncpy(mystring, "some value", 255);
mystring[255] = '\0';

The goal is to keep from overflowing the buffer.

Upvotes: 2

Mike Seymour
Mike Seymour

Reputation: 254431

Can I in this case safely call foo("some value") when I don't know what foo is actually doing (if anything) to its argument?

No. A string literal is constant, and attempting to modify it gives undefined behaviour.

For historical reasons, there is an obsolete conversion to a non-const char* which some compilers will allow - although that conversion is no longer valid since C++11. You should not rely on that, and hopefully you can turn up the warning level on your compiler to prevent it.

To my surprise however, the compiler (gcc 4) is quite happy with this.

That is surprising. My GCC 4.6.3 gives a warning by default; I'd need to specify -Wno-write-strings to silence it.

Upvotes: 9

Neil Kirk
Neil Kirk

Reputation: 21763

No, it's not safe if you cannot guarantee foo won't modify the argument. Compilers can implicitly cast a string literal to char * for backwards compatibility with C code (unfortunately). You will have to copy the literal to a modifiable char buffer and pass that instead.

Upvotes: 11

Related Questions