名前付きの実引数が実現できるかも...

かなり前に書いた「可変個数の実引数の個数」や、本日書いた「マクロの可変個実引数の型を強制する」では、複合リテラルを使って何ができるかを模索しているわけです。この手のネタは、ちょっと考えればまだまだ出てきそうです。今回もそのひとつです。

#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;
}

ちょっと定義が面倒ですが、複合リテラルをうまくつかえば、名前付きの実引数を実現できることがわかります。しかも、名前付きでなくても、従来通り指定した順で、実引数がどの仮引数に対応するかも決まります。

マクロ定義を伴わないといけませんので、どんなにマクロを駆使しても、この関数定義を簡略化することはできそうにありません。どうしてもやるなら、専用のツールを自作するか、これしかないように思います。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/739

[実験] PCP: C Preprocessor

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するようにすれば、それなりに使えるかも。

このエントリーを含むはてなブックマーク