Почему нет ошибки при передаче аргументов командной строки при объявлении main как `int main (void)`?

Случай 1:

void hello(void) {
    //something
}

int main()
{
    hello(1); //error
    return 0;
}

Случай 2:

int main(void) {
    //something
    return 0;
}

Исполнение:

./a.out something something //No error, Why?

Почему нет ошибки? main не сможет принимать какие-либо аргументы. Итак, почему можно предоставить аргументы из командной строки?

Ответы

Ответ 1

Потому что компилятор C и интерпретатор командной строки (или все, что используется для вызова вашей программы) - это разные вещи.

Язык C допускает различные способы, как main() может быть объявлен.

Интерпретатор командной строки сделает любые аргументы доступными для программы. Если программа игнорирует их, то ничто из ее бизнеса.

Интерпретатор командной строки даже не знает, что вы использовали C для компиляции вашей программы. На моем компьютере программа может быть записана в C, С++, Objective-C, Objective-C ++, Swift, Fortran, Ada и т.д. Каждый из этих компиляторов может или не может делать что-то, чтобы принимать команды из командной строки.

Ответ 2

Не проверяя спецификацию и не компилируемый результат, это не вызовет ошибки, так как среда выполнения C получит аргументы и передаст их в main(), но этот тип main() будет игнорировать переданные аргументы и если это вызывающий чтобы очистить память (стек), используемую в качестве аргументов, это не вызовет проблем, как получение некоторых аргументов и не использование их в коде.

Этот код не будет испускать ошибки в C:

void hello(); // in C, the compiler won't check arguments

int main() {
    hello(1); //no error
    return 0;
}

void hello(void) {
    //something 
}

Ответ 3

Потому что ./a.out something something напрямую не вызывает вашу главную функцию. Основная функция вызывается библиотекой времени c. Аргументы командной строки помещаются в область где-то в стеке (в самом начале) во время выполнения загрузчика /c. Это зависит от вас, если вы хотите получить доступ к этим аргументам или нет.

Плюс, как указано в одном из комментариев, по крайней мере, один аргумент командной строки всегда передается (точнее, имя программы ./a.out), поэтому вы должны были спросить об ошибке в этом случае как хорошо.

Ответ 4

Напомним, что ISO C задает две возможные подписи main: int main(void) и int main(int, char *[]) и их эквивалентные версии, такие как int main(int, char **) из-за распада матрицы на указатель. Это описано более подробно здесь.

На этот вопрос можно ответить, обратив внимание на противоположный вопрос: , как среда выполнения C знает, что main для вызова? C не имеет разрешения перегрузки! Это объясняется здесь. Вкратце, другие выталкиваются, но не доступны, потому что для этого нет указания из C.

Ответ 5

Когда вы скомпилируете свою программу с помощью gcc program_name.c, компилятор сообщит о любом возможном предупреждении или ошибке времени компиляции. Поскольку аргументы командной строки не передаются во время компиляции, компилятор не знает об этом, и программа просто игнорирует эти аргументы.

В случае hello компилятор знает прототип этой функции и не ожидает, что в его вызове не будет передан аргумент и, следовательно, сообщает об ошибке в случае любого переданного ему аргумента.