30

execvp is defined thus:

int execvp(const char *file, char *const argv[]);

Which precludes code such as this from being used:

const char* argv[] = {"/bin/my", "command", "here", NULL};
execvp(argv[0], argv);

Was this an accidental omission? Is it safe to const_cast around this? Or do some execvp implementations actually scribble on that memory?

Jonathan Mayer
  • 1,432
  • 13
  • 17
  • 3
    Although the `exec*` family of functions does not modify its arguments as noted in the POSIX specification, do note that on Windows, [`CreateProcess` requires a writable command line](http://blogs.msdn.com/b/oldnewthing/archive/2009/06/01/9673254.aspx). – Adam Rosenfield May 04 '12 at 22:00

2 Answers2

9

The POSIX spec says (http://pubs.opengroup.org/onlinepubs/009604499/functions/exec.html):

The argv[] and envp[] arrays of pointers and the strings to which those arrays point shall not be modified by a call to one of the exec functions, except as a consequence of replacing the process image.

I think the missing (or misplaced) const is simply an historical oddity.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 6
    The missing `const` isn't a historical oddity; rather, it's because you can't convert from a `char**` to a `const char* const*` in C without a cast (but you *can* in C++). – Adam Rosenfield May 04 '12 at 21:57
  • 2
    @Adam: right. That's the answer to the first question in the post. I spaced on that: http://c-faq.com/ansi/constmismatch.html – Michael Burr May 04 '12 at 22:10
  • 2
    See also the RATIONALE section at the end of the POSIX spec for exec. It explains the choice of const omission. – R.. GitHub STOP HELPING ICE May 05 '12 at 02:56
  • @AdamRosenfield Then the standard should add a separate #ifdef __cplusplus declaration that allows C++ program to be const correct. – user877329 Aug 05 '13 at 12:17
-1

I came across this same situation. Because execvp() has a char *const as the second parameter, that means it accepts a constant pointer to a char. Therefore, if you pass it a pointer char it will be able to cast the pointer char to a constant pointer to a char. So, instead of declaring it

const char* argv[] = {"/bin/my", "command", "here", NULL};

try

char* argv[] = {"/bin/my", "command", "here", NULL};

and it will accept argv[] without issue.

Kai Sage
  • 29
  • 1
  • 4
  • I meant pointer constant to a char. I went ahead and corrected the grammar mistake. – Kai Sage Mar 07 '17 at 17:45
  • That just moves the error/warning from the `execvp()` line to the assignment statement (unless you have a very lenient compiler). – Toby Speight Mar 07 '17 at 18:04
  • I tested with both gcc and clang using the -Wall option. It didn't return any errors for me. – Kai Sage Mar 07 '17 at 18:16
  • My usual command (`gcc -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds`) gives `warning: initialization discards ‘const’ qualifier from pointer target type` – Toby Speight Jun 01 '18 at 15:49