2014/03/12

Recent entries from same category

  1. コメントも扱える高機能な C++ 向け JSON パーサ「jsoncpp」
  2. C++ で flask ライクなウェブサーバ「clask」書いた。
  3. C++ 用 SQLite3 ORM 「sqlite_orm」が便利。
  4. zsh で PATH に相対パスを含んだ場合にコマンドが補完できないのは意図的かどうか。
  5. mruby-tflite を Coral Edge TPU 対応した。

C言語で可変子引数扱う場合は va_start/va_arg/va_end を使うのだけど...
#include <stdio.h>
#include <stdarg.h>

void
foo(int n, ...) {
  va_list list;
  int i;
  va_start(list, n);
  for(i = 0; i < n; i++)
    puts(va_arg(list, char*));
  va_end(list);
}

int
main(int argc, char* argv[]) {
  foo(3"foo""bar""baz");  
  return 0;
}
型が拘束出来ない。なので
foo(31"bar""baz");  
こんな呼び出し方が出来てしまうし、コンパイルエラーや警告も出ない。実行時にクラッシュする。
なんか出来ないかなーと思ってマクロの海へ...
#include <stdio.h>
#include <stdarg.h>

void
foo(int n, ...) {
  va_list list;
  int i;
  va_start(list, n);
  for(i = 0; i < n; i++)
    puts(va_arg(list, char*));
  va_end(list);
}

#define bar(...) foo((sizeof((char*[]){__VA_ARGS__})/sizeof(char*)), __VA_ARGS__)

int
main(int argc, char* argv[]) {
  bar("foo""bar""baz");
  return 0;
}
これだと引数の個数指定も要らなくなる。エラーにはならないものの、警告は出るので少しはメリットあるかも。
vaarg.c: In function 'main':
vaarg.c:18:3: warning: initialization makes pointer from integer without a cast [enabled by default]
vaarg.c:18:3: warning: (near initialization for '(anonymous)[0]') [enabled by default]
Posted at by | Edit


blog comments powered by Disqus