2014-11-18 2 views
6

Я переношу много кода Oracle Pro * C под HP-Unix в среду Linux.Откуда это объявление: main _2a ((argc, argv), int argc, char * argv [])

В программе есть только такой основной метод определяется:

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

Я никогда не видел такого decalaration раньше - и ничего с Google не найден. Во всяком случае, он работает, и из того, что я вижу, используется как основная функция.

Может кто-нибудь сказать об этом?

Edit: Хорошая подсказка - есть определение макроса:

# define _2a(list,a1,a2)     list a1;a2; 

Тем не менее не дает четкого представления (для меня ..)

+3

'_2a' скорее всего макрос, определенный в каком-либо файле заголовка. –

+2

Возможно, '_2a' - это макрос. –

+0

Хорошая подсказка - я могу видеть определение макроса. Я обновляю вопрос. – Stefan

ответ

6

Мы просто должны расширить макро. Вы можете использовать gcc -E для вызова только препроцессора; он также расширит все директивы #include, поэтому выход будет уродливым.

Но давайте сделаем это вручную. Аргументы макроса представляют собой последовательности токенов, а не выражения.

Макрос определение:

# define _2a(list,a1,a2)     list a1;a2; 

и призывание является:

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

Аргументы:

  • list ->(argc,argv)
  • a1 ->int argc
  • a2 ->char * argv[]

Выполнение замены дает нам:

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

Это чаще быть написано на нескольких строках:

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

Это старый -style Объявление функции.Он по-прежнему легален во всех версиях C (вплоть до стандарта 2011 года), но с 1989 года он официально устарел. Недостатком этой старой формы является то, что она не передавала информацию о параметрах вызывающим, поэтому компилятор не мог предупредите, если вы вызвали функцию с неправильным количеством типов аргументов.

Держу пари, что есть альтернативное определение _a2 макроса, который расширяется к более современному определению, которое включает прототип, что-то вроде:

#define _2a(list,a1,a2) (a1, a2) 

С этим макроопределением, определение main вместо расширяется до этого :

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

Так _a2 макросъемки («а», предположительно означает «аргумент») позволяет писать код, который может расширить либо для определения функции старого стиля (для компиляторов до ANSI) или для современного определения с прототипом.

разумный способ осуществить это было бы:

#ifdef __STDC__ 
#define _2a(list,a1,a2) (a1, a2) 
#else 
#define _2a(list,a1,a2) list a1;a2; 
#endif 

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

Кроме того, в определении main отсутствует тип возврата int. До стандарта 1999 года было законным опускать возвращаемый тип в соответствии с «неявным int». Стандарт 1999 года отклонил это правило и сделал явный тип возврата обязательным. Большинство компиляторов C в режиме по умолчанию по-прежнему позволяют исключить тип возвращаемого значения, возможно, с предупреждением, но нет никаких оснований его пропускать.

+0

Это очень хорошо написанный ответ, который содержит много информации. Я могу дать только +1, потому что у меня нет +2. Мне очень жаль, что я не принимаю ваш отличный ответ как «ответ», потому что я уже отметил ответ Кей. он предоставил мне необходимую мне информацию и был немного быстрее - также моя собственная политика не позволяет переключать тикающий ответ - я сожалею об этом. В любом случае я призываю всех поддержать этот ответ. – Stefan

+0

@Stefan: В редких случаях, когда я отправляю вопросы, я обычно жду немного, прежде чем принимать ответ. (Я не говорю об этом, чтобы предположить, что мой ответ должен был быть принят, это полностью зависит от вас. Кстати, я поддержал другой ответ.) –

+0

Я бы не обиделся, если вы изменили принятый ответ.Я обычно жду день или два, прежде чем принимать ответ, потому что он привлекает больше посетителей, и часто из-за этого ответы получают более высокие показатели. :) – kay

8

Этот макрос используется для K&R C -стиль функции определения вид больше похожи на «современные» определения C89.

Expanded код гласит:

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

Или с лучшим отступом:

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

Какого древним способом написать:

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

Можете ли вы объяснить, что делает препроцессор? Я пытаюсь выяснить, какая замена выполняется до начала компиляции. – Stefan

+0

Я включил выражение простого макроса в свой вопрос. Отвечает ли это на ваш вопрос? – kay

+0

Вы, сэр, герой! – Stefan

Смежные вопросы