1

I am porting some C code to C++ right now. The C code is using multiple defines like:

#define IPADDRESS "fd9e:21a7:a92c:2323::1"

The problem that i have is that when i am calling C functions with the defines that are now in the C++ file i get:

warning: ISO C++ forbids converting a string constant to ‘char*’

I don't want to modify the C functions in this case and since I am still new to C++ and i was wondering how to handle this problem. I guess it isn't possible to tell C++ to handle these defines as a char* and not as a string constant so i was wondering if it is safe to cast the string constant to a char* in this case or if there is a function that i should use for this?

I appreciate your help!

mab0189
  • 126
  • 12
  • 3
    The correct type for a string constant is `const char *`. The absence of `const` is the problem. –  Jun 14 '21 at 12:41
  • 1
    If you could change the defines themselves, I suppose you could write something like `#define IPADDRESS (char*)"fd9e:21a7:a92c:2323::1"` – Igor Tandetnik Jun 14 '21 at 12:42
  • 2
    You can throw away the constness by a `const_cast(...)` but if something tries to write to them, you may get a crash. –  Jun 14 '21 at 12:44

1 Answers1

2

The problem is that string literals "this is a string literal" are of type char[] in C but const char[] in C++. So if you have sloppily written C code which doesn't use const correctness of function parameters, that code will break when ported to C++. Because you can't pass a const char* to a function expecting char*.

And no, it is generally not safe to "cast away" const - doing so is undefined behavior in C and C++ both.

The solution is to fix the original C code. Not using const correctness is incorrect design, both in C and C++. If the C++ compiler supports compound literals, then one possible fix could also be:

#define IPADDRESS (char[]){"fd9e:21a7:a92c:2323::1"}
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    Worth noting that compound literals are not standard C++. – Aykhan Hagverdili Jun 14 '21 at 13:00
  • Thank you very much @Lundin for this answer. I didn't know that the `const` was the problem here. The C code is using `char * const ipAddress` in the function calls for example. I think changing it to `const char * const ipAddress` could be the best option. I also appreciate that you added the other option with the compount literal. I didn't know that that this is possible in C++. – mab0189 Jun 14 '21 at 13:03
  • 1
    @mab0189 if you can change function argument types to `char const* ...`, then that's the best solution. – Aykhan Hagverdili Jun 14 '21 at 13:05
  • 1
    @mab0189 `char * const ipAddress` as a function parameter usually means that the person who wrote the function didn't have a clue. Or in some very rare cases, that the function expects a read-only storage pointer as input. Compound literals is a C feature, it may not be available in C++ other than as a non-standard extension. – Lundin Jun 14 '21 at 13:05
  • 1
    @Lundin @AyxanHaqverdili I changed the functions to `char const *const` and i it works great. Thank you very much! – mab0189 Jun 14 '21 at 17:17
  • @mab0189 It should just be `const char*`. Everything else is very hard to justify - it makes perfect sense to const qualify what the pointer points at. Not so much to const-qualify local variables just for the sake of it. – Lundin Jun 15 '21 at 06:30