-3

I am trying to call function void func(char** argv) with a string literal "test.exe" in C++. My current solution is

char* name = "test.exe";
func(&name);

However, the compiler complains since string literals are of type const char*. What is the current recommended way to resolve this?

I've read several answers, here, here, here, etc, but all the answers I've found are either:

  1. Use std::string::c_str() which I don't want to do since I don't want to allocate the memory for a new std::string, or

  2. Change func to take a const char *, which I cannot do as it is contained in an external library.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Mickey
  • 1
  • 3
  • 1
    If the function is declared without `const`, that implies that it may modify the string you pass in. So you can't call it with a literal, since they can't be modified. – Barmar May 05 '23 at 22:26
  • 3
    And the name `argv` suggests that it should be an array of strings, not a single string. If the function doesn't also take `argc`, it will expect the array to end with a `NULL` pointer. – Barmar May 05 '23 at 22:28
  • 1
    Side note: `std::string::c_str()` can't help here. It also returns a `const` pointer. `std::string::data`, on the other hand... Will compile but is almost certainly a bad idea. – user4581301 May 05 '23 at 22:30
  • 1
    It's possible that they're just sloppy C programmers. For historical reasons, C string literals are `char*` rather than `const char*`. – Barmar May 05 '23 at 22:30
  • I was just simplifying the problem. The full signature I'm trying to call is `int mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[])` – Mickey May 05 '23 at 22:30
  • It entirely depends on the external lib. The function may never modify and the missing `const` is just a relic of ancient C, allowing you to simply use `const_cast`, it may require the contents pointed to to be modifiable or even to have a minimum size... – fabian May 05 '23 at 22:30
  • 1
    In that case they most certainly want an array of strings. – user4581301 May 05 '23 at 22:31
  • You're meant to just pass in the argc and argv from the terminal, but I wanted to simplify having to provide that every time I test it by just hard coding the values for now – Mickey May 05 '23 at 22:31
  • 1
    Just use `const_cast()` to override the default type of the string literal. – Barmar May 05 '23 at 22:32
  • I agree they want an array of strings @fabian, I'm not positive how I should write that in C though – Mickey May 05 '23 at 22:32
  • Ok so what I have now based on your suggestions is `char* h = const_cast("test.exe");` `mono_jit_exec (domain, assembly, 1, &h);` Is this a good solution? – Mickey May 05 '23 at 22:35
  • Should work. You'll soon know... – Paul Sanders May 05 '23 at 22:38
  • Seems to be working, just hoping this won't cause one of those scary C memory bugs – Mickey May 05 '23 at 22:42
  • Do not tag C for C++ questions. – Eric Postpischil May 05 '23 at 23:02
  • With the (lack of) information given in the question, it is really opinion-based. For example, if `func()` ASSUMES the pointer it is passed is the address of a first element of an array of `char *`, where the end of the array is marked by a null pointer, then the usage `func(&name)` in the question WOULD give undefined behaviour, regardless of any concerns of `const` or otherwise. The general answer is to examine documentation (or code if you have it) for `func()` and pass something that will give well-defined behaviour. – Peter May 06 '23 at 00:34

1 Answers1

2

It depends whether the function actually modifies the string.

If it doesn't, then you can just cast away the const:

char* name = const_cast<char*>("test.exe");
func(&name);

String literals are not allowed to be modified though. That means that if the function does modify the string you pass it, then you'll need to copy the string literal to a local, modifiable variable:

char name_arr[] = "test.exe";
char* name = name_arr;
func(&name);
Miles Budnek
  • 28,216
  • 2
  • 35
  • 52