Что обозначает строка из исходников lighttpd? c++

*(const char **)&argv[0] = BINPATH;

P.s. #define BINPATH SBIN_DIR"/lighttpd"


Ответы (1 шт):

Автор решения: VladimirS

Контекст, я так понимаю, примерно такой:

#define BINPATH SBIN_DIR"/lighttpd" // Соединяем строку макроса SBIN_DIR с "/lighttpd", записываем в SBIN_DIR

int main(int argc, char* argv[]){//argv это char**
   *(const char **)&argv[0] = BINPATH;   
}

Расшифровка:

  1. argv[0] - 0-ая строка, переданная в параметр
  2. &argv[0] - её адрес (указатель на неё). Т.е. строка - указатель/массив символов, а мы берём адрес строки => мы берём указатель на указатель/массив символов
  3. (const char **)&argv[0] - снимаем константность строки (можно было бы попробовать использовать const_cast<const char**>(&argv[0]) вместо этого)
  4. *(const char **)&argv[0] - разыменовываем указатель на строку (указатель на массив символов/указатель), получаем - строку (просто массив символов/указатель)
  5. *(const char **)&argv[0] = BINPATH; - присваиваем строке-аргументу командной строки при вызове программы, другую строку (с учётом константности - из-за которой была вся пляска с приведением типов), де факто - приравниваем один указатель на последовательность символов с другим (просто присваиваем адрес).

Nota bene: хотя такое (я про 5й шаг) в большинстве случаев и прокатывает, т.к. как правило, никто не трогает аргументы запуска программы, но вот если кто-то после 5го шага сделает, например так: argv[0][0] = 'H', то можно ожидать undefined behavior: не константный argv позволяет изменять любой символ в строке, но т.к. мы ему присвоили адрес константной строки, то попытка модифицировать эту строку может иметь непредсказуемые последствия.

→ Ссылка