Гарантируется ли args [0] путь выполнения? - PullRequest
8 голосов
/ 21 декабря 2008

Это фундаментальный вопрос, но важный, тем не менее ...

При запуске программы на C ++, основной метод которой имеет следующую общую подпись:

int main(int argc, char* args[]) {
    //Magic!
    return 0;
}

всегда ли args [0] всегда указывает путь к запущенной в данный момент программе? Как насчет кроссплатформенности (поскольку я нахожусь в среде Linux, но могу портировать позже)?

Ответы [ 4 ]

21 голосов
/ 21 декабря 2008

Это не всегда. Это значение, которое вы дали программе с помощью операционной системы. Например, при запуске программы с использованием exec вы можете установить для нее произвольное значение:

int execve(const char *filename, char *const argv[],
           char *const envp[]);

Первый параметр - это файл для запуска, и argv будет содержать argv [0] и все остальные параметры для main. envp содержит переменные среды (не определенные стандартом C или C ++. Это вещь posix).

Точнее, это определение argv в C ++:

Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Это должно иметь тип возвращаемого значения типа int, но в остальном его тип определяется реализацией. Все реализации допускает оба следующих определения основных:

int main() { /* ... */ }

и

int main(int argc, char* argv[]) { /* ... */ }

В последней форме argc будет количеством аргументов, переданных программе из среды в который программа запускается. Если argc отлично от нуля, эти аргументы должны быть переданы в argv[0] через argv[argc-1] как указатели на начальные символы многобайтовых строк с нулевым символом в конце (NTMBS) (17.3.2.1.3.2) и argv[0] должны быть указателем на начальный символ NTMBS, который представляет имя, используемое для вызова программы или "". Значение argc должно быть неотрицательным. Значение argv[argc] должно быть 0. [Примечание: рекомендуется добавлять любые дополнительные (необязательные) параметры после ARGV. ]

Это в значительной степени зависит от реализации, которая определяет «имя, используемое для вызова программы». Если вы хотите получить полный путь к исполняемому файлу, вы можете использовать GetModuleFileName в Windows и argv[0] (для получения имени, используемого для выполнения, может быть относительным) вместе с getcwd (для получения текущий рабочий каталог, пытаясь сделать имя абсолютным).

5 голосов
/ 21 декабря 2008

Нет. В Windows GetModuleFileName гарантирует точный полный путь к текущей исполняемой программе. В Linux есть символическая ссылка / proc / self / exe. Сделайте ссылку на чтение по этой символической ссылке, чтобы получить полный путь к текущей выполняемой программе. Даже если ваша программа называлась "через", символическая ссылка / proc / self / exe всегда будет указывать на программу actall.

3 голосов
/ 21 декабря 2008

Не гарантировано, что учащиеся пытались скрыть тот факт, что они играли в Rogue на мэйнфрейме школы, написав программы на C, которые начинали бы его с argv [0] из «cc» или «tcsh».

2 голосов
/ 21 декабря 2008

Вот что говорит стандарт C, что argv[0] должно быть:

Если значение argc больше ноль, строка указанная argv[0] представляет название программы; argv[0][0] должен быть нулевым символ, если имя программы не доступно из среды хоста.

Что касается того, содержит ли он полный путь, ответ таков: argv [0] не обязательно содержит полный путь к исполняемому файлу. На Windows это, кажется, именно то, что было предоставлено в командной строке. Не знаю, что делает Linux / Unix.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...