Dies ist nur eine Situation, in der C/C++ Stil const nicht sehr gut funktioniert. In Wirklichkeit wird der Kernel die an exec() übergebenen Argumente nicht ändern. Es wird nur kopiert, wenn es einen neuen Prozess erstellt. Aber das Typensystem ist nicht expressiv genug, um wirklich gut damit umzugehen.
Viele Leute auf dieser Seite schlagen vor, dass exec "char **" oder "const char * const []" nimmt. Aber keiner von denen funktioniert tatsächlich für Ihr ursprüngliches Beispiel. "char **" bedeutet, dass alles änderbar ist (sicherlich nicht für die String-Konstante "/ usr/bin/whatever"). "const char * const []" bedeutet, dass nichts veränderbar ist.Aber dann können Sie den Elementen des Arrays keine Werte zuweisen, da das Array selbst dann const ist.
Das Beste, was Sie tun können, ist eine Kompilierung-C konstant wie dieses:
const char * const args[] = {
"/usr/bin/whatever",
filename.c_str(),
someparameter.c_str(),
0};
Dies wird tatsächlich mit der vorgeschlagenen Art Signatur „const char * const []“ arbeiten. Was aber, wenn Sie eine variable Anzahl von Argumenten benötigen? Dann können Sie keine Kompilierzeitkonstante haben, aber Sie benötigen ein veränderbares Array. Also bist du wieder da, um Dinge zu manipulieren. Das ist der wahre Grund, warum die Typ-Signatur von exec "const char **" für Argumente annimmt.
Die Probleme sind die gleichen in C++ übrigens. Sie können einen std :: vector < std :: string> nicht an eine Funktion übergeben, die einen std :: vector < const std :: string> benötigt. Sie müssen den gesamten std :: vector schreiben oder kopieren.
Ich denke, Sie können const_cast sicher verwenden, wenn Sie sicher sind, dass das Programm, das Sie ausführen, seine Argumente nicht ändert. Implementierung von execv() nicht. – Vanuan
Ich habe C++ - Wrapper für jeden Systemaufruf geschrieben, den ich mache, so dass der Systemaufruf Ausnahmen auslöst, anstatt dass ich die Rückgabewerte überprüfen muss. Als Teil davon habe ich gerade eine Reihe von Überladungen gemacht, die alle "const_cast" für mich machen, so dass ich sie nicht über den ganzen Code streuen lassen muss. Sie brauchen Definitionen von execve, damit dies funktioniert, weil für beide Argumente const/non-const gilt. Einer ist natürlich die Systemdefinition. Die anderen sind nur Inline-Funktionen, die zu den gegebenen Casts weitergeleitet werden. – Omnifarious