[/b/] [/d/] [/tu/] [/a/] [/ph/] [/wa/] [/cg/] [/t/] [/p/] [/dev/] [/stat/] ]
[Burichan] [Futaba] [Gurochan] [Tomorrow] [Архив-Каталог] [Главная]

Файл: 1695503129510.jpg -(248 KB, 1536x1536, 1695503129510.jpg)
248 No.217684  

Пердолился сегодня с макросами на Си. Мне нужно внутри тела функции знать ее возвращаемый тип чтоб автоматически сгенерировать его "нулевое" значение. Как я понимаю в сколько-нибудь чистом виде эта задача не решаема. Сейчас объявляю функции так:

fun( Sum, int ) ( int A, int B ) ( return A + B; )

Выглядит терпимо, но хотелось бы чего-то получше. Экспандится ~примерно~ в такое:

int Sum_Return_Value; int Sum ( int A, int B ) { typeof( Sum_Return_Value ) ERROR_Return_Value; return A + B; }

Есть еще макросы для генерации ошибки, которые вайпают ERROR_Return_Value и возвращают его. (Инфа об ошибке пушится в специальный стек.)

>> No.217685  
Файл: 1695503227804.jpg -(175 KB, 1536x1536, 1695503227804.jpg)
175

Простите великодушно, не хотел новый тред имени меня, но что-то пошло не так...

>> No.217686  

Зачем делать глобальную переменную, если можно делать локальную статическую переменную внутри функции?

>> No.217687  

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

>> No.217688  

>>217687
Глобальная переменная у меня статическая на самом деле, но про констатность я не додумался.

>Зачем делать глобальную переменную, если можно делать локальную статическую переменную внутри функции?

А как я узнаю какого типа должна быть эта переменная внутри функции? Можно конечно наваять макросы типа:
#define start( Name, Return_Type, ...) Return_Type Name (VA_ARGS) { \
Return_Type ERROR_Return_Value;
#define end }
Но как-то не по фэньшую.

>> No.217690  

>>217684
_Generic и по функции на каждый тип?

>> No.217691  

>>217690
Но этот дженерик прийдется держать в одном файле, а типы могут быть из нескольких проектов. Не хотелось бы.

>> No.217693  
#define ESC(...) __VA_ARGS__

#define F(ret_t,fun_name,args,body) \
ESC ret_t fun_name (ESC args) \
{ \
static const typeof(ESC ret_t) ERROR_Return_Value; \
ESC body \
}

F((int), sum, (int a, int b),(
{
return a+b;
}
))
>> No.217694  

>>217693
Вот этого я и хочу избежать. Слишком много визуального шума и скобочек. В моем случае я испозую вызов макросов по цепочке:
#define fun( blah ) ... args
#define args( blah ) ... body
#define body( blah ) ...

поэтому fun( Sum, int ) ( int A, int B ) ( return A + B; )
это три последовательных вызова макроса. Я попробовал только что как-то пробросить возвращаемый тип по этой цепочке но обломинго. ЧСХ только что случайно наткнулся на вопрос на стэковерфлоу по этой же теме, но ответ увы мимо кассы (предлагается "нулевые" значения возвращать вручную).

>> No.217696  

>>217694

#define F(ret_t,fun_name) \
ret_t fun_name F2 (ret_t,

#define F2(ret_t, ...) \
(__VA_ARGS__){static const typeof(ret_t) ERROR_Return_Value; F3

#define F3(...) __VA_ARGS__}

F(int, sum) int a, int b) (return a+b;)
>> No.217697  
Файл: 1695538435358.jpg -(242 KB, 1024x715, 1695538435358.jpg)
242

>>217684
просто раст юзай, там есть дженерики нормальные и сишный код вызывать можно.

или вообще скалу, заодно уважаем будешь.

>> No.217698  
Файл: 1695539901939.jpg -(319 KB, 1370x973, 1695539901939.jpg)
319

>>217684
а, эт, ещё же ЗИГ есть. на нём тут новый рантайм для джаваскрипта нахуячили. зиг создаёт сишный код, у него вообще нет собственного конпелятора. становись зиггером, если не хочешь носить программистский носки с растодевочками.

>> No.217701  

https://github.com/Hirrolot/metalang99

>> No.217704  

>>217697
Если ты за деньги пишешь для кого-то код, переход на какой-то другой язык без согласования (которого очевидно не будет т.к. надо всех других пересаживать на какой-то другой язык и всё переписывать, а это затормозит разработку и вообще лишний геморрой) невозможен.

>> No.217705  
Файл: 1695574739434.jpg -(228 KB, 1045x1097, 1695574739434.jpg)
228

>>217704
тебе кто-то за деньги в продакшен разрешил эту хуиту на макросах городить? не верю.

>> No.217706  
Файл: 1695575244041.gif -(1 KB, 45x19, 1695575244041.gif)
1

>>217704
хотя если у вас макросы городят, то реально подкинь на планёрке зиг. самое то up yours.

фапча говорит у мелкоченьского линька?

>> No.217708  

>>217705
Я не ОП вообще, но ничего необычного в нагораживании макросов в продакшене нет. Там даже всякие кодогенерирующие костыли могут встраивать запросто.

>> No.217716  

>>217706

>shed

bikeshedding же

>> No.217734  

>>217696
Несбалансированные скобочки смертный грех, увы. Пока у меня так:

#define fun( C_Type, Name )  static C_Type MY( ERROR_Result );  C_Type Name fun_ARGS
#define fun_ARGS(...) (__VA_ARGS__) { \
typeof( MY( ERROR_Result ) ) ERROR_Result; memset( (void*) &ERROR_Result, 0, sizeof( ERROR_Result ) ); \
fun_BODY
#define fun_BODY(...) \
{__VA_ARGS__} \
}

Нужно будет еще подумать что делать если функция возвращает void. Макросы для работы с ошибками в применении выглядят примерно так:

let F = OK( Open_Frobnicator() );
let Frob_Count = TRY( Frobnicate( F ) );
OK( Frob_Count <= 19, "Too many frobs" ); NO( Frob_Count < 5, "Too few frobs" );
FIXME_OK( Frob_Count <= 10, "Can't handle more than 10 frobs yet" );
DIE( "Все, заебался!" );
DIE(); //REALITY COMPROMISED

Допилю еще немного и попробую поспрашивать публичных экспертов по си-пердолу. Сомневаюсь что предложат что-то лучше, но хз, я ж не сорок лет упарываю си, может я что-то упускаю из вида.

>>217697

>раст юзай, там есть дженерики нормальные

У меня серьезные сомнения что в расте хоть что-то нормальное. Это как wayland vs xorg, нам обещали что ошибки xorg будут учтены, но как известно что-то пошло не так. То же и с rust vs c++. Хотя говорят что вейленд уже допилили до чего-то вменяемого, не проверял.

>скалу, заодно уважаем будешь.

Заодно можно будет чаек попить пока реконпиляция. Или они уже это поправили.
>>217698
Собственный конпелятор они как раз пишут, чтоб выкинуть LLVM. Вот я и жду когда это произойдет. Тогда и посмотрю внимательнее что за зверь. Собственно на таких затыках си и держиться до сих пор. Для меня важной задачей является бутстраппинг, не хочу зависить от си вообще, но пока лучше уж поебусь с GCC, чем конпелять LLVM (весьма нетривиально) и затем еще фронтенд для языка.

>> No.217736  
Файл: 1695666309721.jpg -(189 KB, 800x1000, 1695666309721.jpg)
189

>>217734
ебать ты бесноватый. вызывает уважение. напиши потом что получится.

>> No.217803  

>>217734

>Несбалансированные скобочки смертный грех, увы.

Тогда как тебе такой вариант?

#define F(ret_t,fun_name, ...) \
ret_t fun_name (__VA_ARGS__){static const typeof(ret_t) ERROR_Return_Value; F2

#define F2(...) __VA_ARGS__}

F(int, sum, int a, int b) (return a+b;)

Или тут тоже скобочки не по фэншую?

>> No.217804  

>>217803
Сейчас у меня так:

fun( int,Sum, int A, int B ) return A + B; end

Примерно то же самое. Проблема с передачей тела как аргумента макроса в том что LINE внутри всего тела имеет одно значение (номер линии на которой закрываящая скобка вызова макроса). А я LINE использую для указания места ошибки. Крч сам я пердолиться с этим больше не буду. Спрошу пару человек, на этом все.




[/b/] [/d/] [/tu/] [/a/] [/ph/] [/wa/] [/cg/] [/t/] [/p/] [/dev/] [/stat/] ]
[Burichan] [Futaba] [Gurochan] [Tomorrow] [Архив-Каталог] [Главная]