Является ли args [0] гарантией того, что это путь исполнения?

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

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

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

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

Ответ 1

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

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

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

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

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

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 (для получения текущего рабочего каталога, пытаясь сделать абсолютное имя).

Ответ 2

Нет. В Windows GetModuleFileName gurantees - полный полный путь к текущей исполняемой программе. В linux есть symlink/proc/self/exe. Сделайте readlink на этой символической ссылке, чтобы получить полный путь к текущей исполняемой программе. Даже если youprogram был вызван tough, symlink/proc/self/exe всегда будет указывать на программу эквалайзера.

Ответ 3

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

Ответ 4

Здесь в стандарте C указано, что argv[0] должно быть:

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

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