1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C言語における共用体と構造体による、構造体の Wrapper 処理

Last updated at Posted at 2016-12-27

1年目プログラマです
レガシーなプログラムになるので、
使う際は注意していただければと思います。
今回は、暫定的な対処をした際の覚え書き

** 修正済み **

概要

C 言語で old という構造体がもともとあり、
そのアドレスを引数として様々な関数があるプログラムに
new という構造体を追加し、使い分けたい場合、
Wrapper 処理を行うことで変更点を少なくする対処法

コード

#include <stdio.h>

/* 元からある構造体 */
typedef struct oldbox oldbox_t;
typedef struct old1 old1_t; // メンバ変数 mem を持つ
typedef struct old2 old2_t;

struct oldbox
{
  old1_t _old1;
  old2_t _old2;
};

void print_struct( oldbox_t *ptr)
{
  printf("%d\n",ptr->old1.mem);
}

void main(void)
{
//略
print_struct( ptr); /* ptr は oldbox型ポインタ */ 
}

これに struct new1 と struct new2 をメンバとして持つ、struct newbox を作成し、print_struct を使いまわす。

共用体を利用した wrapper 処理

/* 新しい構造体 */
struct wrapper
{
  union{
    oldbox_t oldbox;
    newbox_t newbox; // struct new1 と struct new2 をメンバとして持つ
  }box_type;
};

二つをまとめて wrapper とした。

print_struct を使いまわし

このままだと、 oldbox_t と newbox_t の構造体のサイズが異なる場合に、
print_struct 関数を二つ作らないといけないが、それは面倒

/* FLAG is (static) global variable */
#define OLD 1
#define NEW 2

print_struct ( wrapper *ptr)
{
  if( FLAG == OLD){
    oldbox_t *p = &(ptr->box_type.oldbox);
    printf("%d\n",p->old1.mem);
  }
  else if(FLAG == NEW){
    newbox_t *p = &(ptr->box_type.newbox);
    printf("%d\n",p->new1.mem2); // new1 は mem2 というメンバを持っている
  }
}

まとめ

とりあえず暫定的に対処できた。
本当は、構成から考え直すべきだが、時間と量的に
今回はこの方法にした。
しかし、FLAG による分岐を利用しているため
根本的解決法にはなっていない。

よりよい方法があれば教えていただきたいです。

1
4
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?