Arhn - архитектура программирования

Почему программа компилируется?

Я просто пытаюсь понять этот код C (не пытаясь достичь какой-либо функциональной цели с помощью программы). Это компилируется с использованием gcc. Является ли это основным в формате main(int a, char *argv[])? Можно ли объявлять что-либо между аргументом и телом функции (аналогично char *a; здесь)?

#include <stdio.h>
main(u,_,a)
  char
  *a;
{
  //printf("%s\n",_,a);//just to help debugging
  //printf("%d\n",u); //just to help debugging
}
19.12.2013

  • Похоже на функцию стиля до C89. 20.12.2013
  • Добавлю забавный факт, не заслуживающий ответа: мне пришлось использовать этот стиль объявления функций при написании 16-битной загружаемой программы. gcc не компилируется в 16-битный, поэтому мне пришлось использовать bcc (компилятор C Брюса), который не поддерживает ANSI. Так что вы можете столкнуться с этим в некоторых областях! 20.12.2013

Ответы:


1

Это старый, устаревший способ написания функций C.

В языке-предке C не было типов: все переменные содержали машинное слово. Таким образом, определение функции будет начинаться так:

main(u, _, a) {
    /* ... some code ... */
}

С, каким он был раньше, известный как "K&R C" от авторов основной книги о C (Брайан Керниган и Деннис Ритчи) добавили типы в форму которые выглядели как объявления переменных и находились между списком параметров функции и кодом функции.

int main(u, _, a)
    int u;
    int _;
    char *a;
{
    /* ... some code ... */
}

В K&R C, если тип int, то во многих местах его можно опустить. Для параметра функции можно вообще опустить строку объявления типа.

int main(u, _, a)
    char *a;
{
    /* ... some code ... */
}

ANSI C был стандартизирован в 1989 г., и одним из его основных нововведений стала функция прототипы. В правильном ANSI C вы объявляете все функции перед использованием и объявляете типы всех аргументов.

int main(int u, int _, char *a)
{
    /* ... some code ... */
}

Компиляторы C по-прежнему поддерживают старую форму для устаревшего кода. (Если они соответствуют стандарту C 1989 года, то должны.) Спустя более 20 лет осталось не так много унаследованного кода, поэтому вы не часто найдете такой код.

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

19.12.2013

2

Объявления между списком аргументов и телом функции были частью так называемого K&R C (первой версии C). Так что да, они действительны, если ваш компилятор может скомпилировать код K&R.

О том, что main() имеет более двух аргументов... да, на самом деле main может иметь до трех аргументов:

int main (int argc, char *argv[], char *envp[]);

Третий аргумент представляет собой массив указателей на строки, каждая из которых содержит определение переменной среды (строка в форме name=value).

19.12.2013

3

Это старое объявление, которое больше никто не использует, кроме запутывания (см. также: триграфы!). Я думаю, что это незаконно в соответствии с новыми стандартами C, но gcc по-прежнему поддерживает его для обратной совместимости.

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

main(argc, argv)
    int argc;
    char** argv;
{
    printf("%d\n", argc);
    return 0;
}

Вы не можете объявлять другие переменные перед открывающей фигурной скобкой. Попробуйте добавить int c; и получите эту ошибку:

test.c:4: error: declaration for parameter ‘c’ but no such parameter
19.12.2013

4

Это недопустимая форма объявления main. Это неверно в C99/C11, но также недействительно в C90. (См. 5.1.2.2.1 для допустимых объявлений функции main в C90).

19.12.2013
  • Итак, ответ на вопрос, почему он все же компилируется, заключается в том, что GCC слишком либерален. 20.12.2013
  • Хотя технически это верно, это чрезвычайно бесполезно и не отвечает на вопрос, почему компилятор может принять такой недопустимый код. 20.12.2013
  • Это потому, что это K&R c. Все неуказанные типы int. 20.12.2013
  • @ouah Яп, к сожалению. 20.12.2013
  • @ user1741125, как я уже сказал, это 5.1.2.2.1 в C90. Это 2.1.2.2 в C89. Что касается C99 и C11, то больше не допускается опускать возвращаемый тип int для объявлений функций. 20.12.2013
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..