Недавно я увидел что-то любопытное. В исходном коде HHVM самые первые 3 строки main()
Функция читается следующим образом:
if (!argc) {
return 0;
}
Это немного глупо, но все же, я просто не могу не задаться вопросом … зачем возвращать 0 !? Не то, чтобы я думал, что есть какой-то правильный способ справиться с этим, но возвращение 0, обычно связанное с успехом, кажется особенно неуместным.
Кроме того, не сбой, есть ли Когда-либо случай, когда есть соответствующий ответ на argc
быть 0? (Или даже меньше 0?) Это когда-нибудь имеет значение?
Единственный известный мне способ оказаться в случае с argc
из 0 с exec()
и друзья. Если по какой-то причине это происходит, это почти наверняка ошибка в вызывающей стороне, и вызываемый не может ничего с этим поделать.
(помечены как C и C ++, потому что я ожидаю, что ответ одинаков для двух языков)
Редактировать: Чтобы попытаться сделать вопрос менее размытым и философским, я предложу альтернативу.
if (!argc) {
puts("Error: argc == 0");
return 1;
}
Ключевым моментом является то, что есть указание на ошибку и возвращается ненулевое значение. Крайне маловероятно, что это понадобится, но если бы это было так, вы могли бы также попытаться указать на ошибку. С другой стороны, если обнаруженная ошибка столь же серьезна, как argc
равным 0, возможно, есть причина, по которой было бы плохо пытаться получить доступ к stdout или стандартной библиотеке C.
Я думаю, что это просто случай Оборонительное программирование из-за следующего фрагмента в HHVMВолшебный код (файл ГПГП / hhvm / main.cpp):
int main(int argc, char** argv) {
if (!argc) {
return 0;
}
HPHP::checkBuild();
int len = strlen(argv[0]);
В соответствии:
int len = strlen(argv[0]);
если argc == 0
-> argv[0] == NULL
а также strlen(argv[0])
вызовет ошибку сегментации.
Я не знаком с HHVM но они могут просто предположить, что какая-то программа может вызвать программу без аргументов (даже без имени программы).
Обратите внимание, что стандарт C11 явно допускает argc == 0
:
5.1.2.2.1 Запуск программы
Called1 Функция, вызываемая при запуске программы, называется
main
, Реализация заявляет нет
прототип для этой функции. Это должно быть определено с типом возвратаint
и без
параметры:int main(void) { /* ... */ }
или с двумя параметрами (упоминается здесь как
argc
а такжеargv
хотя могут быть любые имена
используется, поскольку они являются локальными для функции, в которой они объявлены):int main(int argc, char *argv[]) { /* ... */ }
или эквивалент;10) или каким-либо другим способом, определяемым реализацией.
If2 Если они объявлены, параметры к
main
функция должна подчиняться следующему
ограничения:
- Значение argc должно быть неотрицательным.
argv[argc]
должен быть нулевым указателем.- Если значение
argc
больше нуля, члены массиваargv[0]
через
argv[argc-1]
включительно должен содержать указатели на строки, которые даны
определенные реализацией значения хост-средой до запуска программы.
намерение состоит в том, чтобы предоставить программе информацию, определенную до запуска программы
из другого места в размещенной среде. Если среда хоста не способна
предоставление строк с буквами в верхнем и нижнем регистре, реализация
убедитесь, что строки получены в нижнем регистре.- Если значение
argc
больше нуля, строка указанаargv[0]
представляет название программы;argv[0][0]
должен быть нулевым символом, если
Имя программы недоступно из среды хоста. Если значениеargc
является
больше единицы строки, на которые указываетargv[1]
черезargv[argc-1]
представлять параметры программы.- Параметры
argc
а такжеargv
и строки, на которые указываетargv
массив должен
быть изменяемыми программой и сохранять их последние сохраненные значения между программами
запуск и завершение программы.10) Таким образом,
int
может быть заменено именем typedef, определенным какint
или типargv
можно записать как
char ** argv
, и так далее.
Два пулевых пункта говорят: «если значение argc
больше нуля «четко разрешить argc == 0
хотя это было бы необычно для этого.
Поэтому теоретически программа может принять меры предосторожности против этого, хотя argv[0] == 0
даже если argc == 0
, так что пока код не разыменует нулевой указатель, все должно быть в порядке. Многие программы, возможно даже большинство, не принимают такие меры предосторожности; они предполагают, что argv[0]
не будет нулевым указателем.