C言語でnewもどきを作ってみる。
複合リテラル(と可変個実引数マクロ)に関する話題が続いています。今回もその一環なのですが、どちらかといえば、どこに複合リテラルを使っているのだろうと、探さなければならないほどの脇役です。
今回のテーマは、C++のnew演算子のようなものをCで作ってみるというものです。この類のマクロは、いろいろな人が挑戦しているようですが、複合リテラルと可変個実引数マクロを組み合わせることで、なかなかよいものができそうです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define c_new(type, ...) \
((type*)memcpy(malloc(sizeof(type)), \
(struct{char dummy_;type init_[1];}){0,__VA_ARGS__}.init_, sizeof(type)))
struct A
{
int a, b;
};
int main(void)
{
struct A *p1 = c_new(struct A);
struct A *p2 = c_new(struct A, {1, 2});
printf("%d %d\n", p1->a, p1->b);
printf("%d %d\n", p2->a, p2->b);
return 0;
}
#include <stdlib.h>
#include <string.h>
#define c_new(type, ...) \
((type*)memcpy(malloc(sizeof(type)), \
(struct{char dummy_;type init_[1];}){0,__VA_ARGS__}.init_, sizeof(type)))
struct A
{
int a, b;
};
int main(void)
{
struct A *p1 = c_new(struct A);
struct A *p2 = c_new(struct A, {1, 2});
printf("%d %d\n", p1->a, p1->b);
printf("%d %d\n", p2->a, p2->b);
return 0;
}
気になるのはオーバーヘッドですが、GCCで確認した限りでは特に問題なさそうです。というか、期待以上に最適化が効いています。もちろん、ターゲットにもよるのでしょうが、少なくともパフォーマンスに関しては十分使い物になる気がしています。
この記事のトラックバックURL:
http://www.kijineko.co.jp/trackback/740
