Какво означава typedef A (*AF)()?

Основният ми език за програмиране, j, наскоро беше отворен- източник. За да го подобря, изучавам източника, който е написан на C.

Но мина много (!) време, откакто не съм чел или писал C, а тогава дори не бях добър в него. И начинът, по който е написана тази конкретна кодова база, е ... идиосинкратичен (много интерпретатори на APL, J сред тях, имат изходния си код, написан в "APL стил" от високо ниво, дори когато са написани на език от ниско ниво; много кратък, излишъкът е избегнат , тежка макро употреба и т.н.)

В момента се опитвам да разбера основните структури от данни, които използва. Най-фундаменталният е typedef A ("A" е за "масив"):

typedef struct {I k,flag,m,t,c,n,r,s[1];}* A;

което разбирам добре. Но се мъча да си обясня какво е AF, два реда по-късно:

typedef A (*AF)();

Какво означава този синтаксис? По-специално, какво означава, когато нещата по-късно се декларират като "тип AF"? AF просто указател ли е към A?

Непосредствената ми цел е да интерпретирам дъмпове на паметта, които включват неща от тип V (за "глагол"), чиито първи два члена са AFs:

typedef struct {AF f1,f2;A f,g,h;I flag,mr,lr,rr,fdep;C id;} V;

но общата ми цел е по-голяма от това, така че, моля, разработете по-подробно синтаксиса, използван в дефиницията на AF.


c j
person Dan Bron    schedule 11.08.2015    source източник
comment
AF е указател към функция, която не приема параметри и връща A.   -  person Sergey Kalinichenko    schedule 11.08.2015
comment
@dasblinkenlight: Това е вярно в C++. В C това е typedef за функция с неопределен, но фиксиран брой и тип(ове) параметри и връща A. Много вероятно трябва да се дефинира като typedef A (*AF)(void);. Ако наистина е предназначено да приема произволен брой аргументи, тогава можете много лесно да имате недефинирано поведение, като извикате функция неправилно, без диагностика от компилатора.   -  person Keith Thompson    schedule 11.08.2015
comment
Тази кодова база е ужасна. Трябва да бягате с писъци.   -  person Hogan    schedule 11.08.2015
comment
@KeithThompson Worth отбелязва, че в J функциите могат да приемат или един аргумент (и двата от тип A) или два аргумента (от тип A) и винаги да връщат A. Няма такова нещо като функция с нула или повече от два аргумента, или функция, която приема аргументи от всичко с изключение на тип А. Странното за мен е, че казвате, че AF може да приема фиксиран брой аргументи: струва ми се, че трябва да може да приема един или два.   -  person Dan Bron    schedule 11.08.2015
comment
Няма начин в C да се посочи, че една функция може да приема един или два аргумента. Повечето функции приемат фиксиран брой аргументи, определени, когато функцията е декларирана/дефинирана; това число може да бъде навсякъде от 0 до всяко абсурдно голямо число, което компилаторът поддържа. Функция, декларирана с (), приема фиксиран, но неопределен брой аргументи. Съответната дефиниция определя действителния брой и тип(ове) на параметрите. Това е остаряла функция. Променлива функция, като printf, се декларира/дефинира с , ... и приема N фиксирани аргумента плюс 0 или повече ...   -  person Keith Thompson    schedule 11.08.2015
comment
... допълнителни аргументи. В C++ можете да претоварите функция, така че да има две версии, A func(A) и A func(A, A); това биха били две различни функции, които имат едно и също име. C няма претоварване, но можете да дефинирате A func1(A) и A func2(A, A). (Не познавам J, така че не мога да коментирам как работи.)   -  person Keith Thompson    schedule 11.08.2015
comment
Това означава, че използвате грешен език!   -  person Dov    schedule 11.08.2015
comment
Лаконичността на J очевидно си е проправила път към изпълнението с ужасни резултати.   -  person Paul Draper    schedule 11.08.2015
comment
За пример, при който коригирането на това, което някои хора наричат ​​ужасно, би довело до нещо много по-лошо, помислете за FARPROC, който е указател към функция в динамично свързана библиотека (където броят и типовете аргументи са посочени като левия аргумент на cd ).   -  person rdm    schedule 12.08.2015
comment
@rdm До голяма степен не съм запознат с C: можеш ли да обясниш защо коригирането на FARPROC би влошило ситуацията и защо някои хора може да смятат FARPROC за ужасен на първо място?   -  person Dan Bron    schedule 12.08.2015
comment
Някои хора твърдят, че аспектът с неопределен брой аргументи на typedef е остаряла функция на C, така че това е един източник на ужас. Междувременно коригирането му вероятно би означавало елиминиране на възможността за извикване на произволни динамично свързани функции. (Или би означавало да го замените с нещо много по-подробно, което вероятно ще разбие L1 кеша).   -  person rdm    schedule 12.08.2015
comment
За коментар на horrible: Ето въпроси и отговори от автора: Q Как конвенционалните C програмисти реагират на това? О: С Ужас! --- Презентация на Роджър Хуи пред Британската асоциация на APL на 12 февруари 1993 г.   -  person ahala    schedule 12.08.2015


Отговори (3)


Както вече беше отговорено, AF (функция на масив) е указател към функция, която връща A (указател на обект на масив).

В дефиницията на V (Глагол, т.е. функционален обект) има две AF. v1 е указател към изпълнението на монадичната функция, а v2 е указателят към диадичната функция. Ако V представлява оператор (наречие), тогава v1 и v2 все още са съответно монадични и диадични реализации, но също така f g и h могат да се използват за задържане (изкривени) леви и/или десни аргументи. mr lr и rr са съответно монадичен ранг, ляв ранг и десен ранг. И id съдържа операционен код, така че представяне за печат все още може да бъде възстановено от структурата.

Ако някой от операндите в f g или h сами по себе си са глаголи, тяхната V структура ще бъде на f->k байта след *f, съответно за g и h, като всички "данни за полезен товар".

Много полезна връзка, която намерих за разбиране на основните типове в имплементацията на J, е Бележки за разговор на Roger Hui BAA (2.69M сканиран pdf). Пълният текст е на адрес Внедряване на J (html).

Може също да намерите моя примитивен клонинг за поучителен. Вижте също въпросите ми тук и тук.

person luser droog    schedule 11.08.2015
comment
Страхотен, много специфичен за моите нужди (чудех се за f, g, h). Благодаря. Ще разгледам бележките на BAA и вашия клонинг. Оценявам помощта. - person Dan Bron; 11.08.2015
comment
Приех вашия отговор, въпреки че беше по-късно от другите, защото съдържа най-много подробности, специфични за моя проект (струва си да се спомене, че гласувах за всички публикувани отговори). - person Dan Bron; 11.08.2015

AF е typedef за указател на функция. По-конкретно, AF се отнася до указател към функция, която приема неопределен брой параметри и връща резултат от тип A.

person dbush    schedule 11.08.2015
comment
А, разбира се. Това има смисъл и в контекста на Vs, които са функции, които обработват As (и връщат As). Благодаря. Ще приема това, когато системата ми позволи. - person Dan Bron; 11.08.2015
comment
Това е указател към функция с 0 аргумента. Указателите към функции с променлив брой аргументи използват ... синтаксис. - person rlbond; 11.08.2015
comment
@rlbond Не, функция с 0 аргумента има (void) като списък с параметри; това би било typedef A (*AF)(void). Отговорът е правилен: това е неопределен брой параметри. - person Filipe Gonçalves; 11.08.2015
comment
@rlbond: Функциите, декларирани с (), са много различни от променливите функции, декларирани с , .... Първото означава, че все още трябва да предавате аргументи, съответстващи на дефиницията, но компилаторът няма да открие грешки (това е остаряла функция). Последното означава, че функцията може законно да приема различен брой и тип(ове) аргументи; printf е най-честият пример. - person Keith Thompson; 11.08.2015
comment
AF не е указател, а тип. Моля, опитайте се да останете точни. - person alk; 11.08.2015
comment
@alk Благодаря. Променен е указател към препраща към указател - person dbush; 11.08.2015

Нека пренебрегнем какво всъщност е A. Тогава имате

typedef int (*AF)();

AF е указател към функция (известен още като указател на функция), който приема произволен брой аргументи и връща int. Ясно е, че чрез заместване на int с A, съдържанието е по същество същото с изключение на типа на връщането; следователно крайният резултат квалифицира AF като указател към функция, приемаща произволен брой аргументи и връщаща A, псевдоним за указател към анонимна структура.

Има един интересен сайт, който може да помогне за преобразуването на сложни декларации в четим от човека текст.

person edmz    schedule 11.08.2015
comment
хубаво. Благодаря по-специално за връзката към cdecl.org: вероятно ще ми трябва за този проект. - person Dan Bron; 11.08.2015
comment
@DanBron: Има и програма cdecl, която можете да инсталирате. За Linux просто инсталирайте пакета cdecl. За други операционни системи вероятно можете да го изградите от изходния код. - person Keith Thompson; 11.08.2015