名前付きの実引数が実現できるかも...
かなり前に書いた「可変個数の実引数の個数」や、本日書いた「マクロの可変個実引数の型を強制する」では、複合リテラルを使って何ができるかを模索しているわけです。この手のネタは、ちょっと考えればまだまだ出てきそうです。今回もそのひとつです。
#include <stdio.h>
struct A
{
int param1, param2, param3;
};
#define foo(...) test((struct A[1]){{__VA_ARGS__}})
void test(const struct A *a)
{
printf(".param1 = %d\n", a->param1);
printf(".param2 = %d\n", a->param2);
printf(".param3 = %d\n", a->param3);
}
int main(void)
{
foo(.param3=3, .param1=1);
return 0;
}
struct A
{
int param1, param2, param3;
};
#define foo(...) test((struct A[1]){{__VA_ARGS__}})
void test(const struct A *a)
{
printf(".param1 = %d\n", a->param1);
printf(".param2 = %d\n", a->param2);
printf(".param3 = %d\n", a->param3);
}
int main(void)
{
foo(.param3=3, .param1=1);
return 0;
}
ちょっと定義が面倒ですが、複合リテラルをうまくつかえば、名前付きの実引数を実現できることがわかります。しかも、名前付きでなくても、従来通り指定した順で、実引数がどの仮引数に対応するかも決まります。
マクロ定義を伴わないといけませんので、どんなにマクロを駆使しても、この関数定義を簡略化することはできそうにありません。どうしてもやるなら、専用のツールを自作するか、これしかないように思います。
この記事のトラックバックURL:
http://www.kijineko.co.jp/trackback/739

PHPで前処理をさせれば...
#include <stdio.h>
<?php
function deffn($name, $args, $rettype)
{
echo "struct parameters_$name { $args };\n";
echo "#define $name(...) \\\n";
echo "\tfunction_$name((struct parameters_${name}[1]){{__VA_ARGS__}})\n";
echo "$rettype function_$name(struct parameters_$name *args)\n";
}
?>
<?php
deffn('test', 'int param1; int param2; long param3;', 'void');
?>
{
printf(".param1 = %d\n", args->param1);
printf(".param2 = %d\n", args->param2);
printf(".param3 = %d\n", args->param3);
}
int main(void)
{
test(.param3=3, .param1=1);
return 0;
}
こんな感じか。deffn関数(名前はちょっと考えもの)の定義をrequireするようにすれば、それなりに使えるかも。