プログラムにプロトタイプを追加するprotoizeについて,
またプロトタイプを削除するunprotoizeについて

 ツールであるprotoizeは,プログラムにプロトタイプを追加するために使用します.これにより,プログラムプロトタイプ宣言や引き数の型の取り扱いに関してANSI C方式に変換されます.一緒に提供されているunprotoizeがこの逆のことを行います.こちらは,プロトタイプを見つけると,そこから引き数の型情報を取り除きます.

 これらのプログラムを実行する際には,ソースファイルをコマンドライン引き数として指定しなければなりません.変換プログラムは,ソースファイルの中でどのような関数が定義されているかを調べるために,まずそれらをコンパイルすることから始めます.

 その後に変換を行いますが,カレントディレクトリにあるソースファイルやヘッダファイルだけを変換します.

 あるディレクトリの下のファイルを変換したい場合には,-d directoryオプションでその追加のディレクトリを指定することが可能です.変換の対象外としたい特定のファイルを-x fileオプションで指定することも可能です.

 protoizeによる基本的な変換は,引き数の型を指定するために関数定義や関数宣言を書き直すことです.可変個数の引き数を取る関数定義や関数宣言については変換しません.

 protoizeは,ソース上で関数定義よりも前にある関数呼び出しから利用できるように,ソースファイルの先頭にプロトタイプ宣言を挿入するようにすることもできます.

 また,宣言されていない関数が呼び出されているブロックの中に,ブロックスコープをもつプロトタイプ宣言を挿入することもできます.

 unprotoizeによる基本的な変換では,ほとんどの関数宣言を書き直して引き数の型を取り除き,ANSI以前の旧方式の形式に関数定義を書き直します.

 protoizeやunprotoizeからの出力は,元のソースファイルを置き換えます.元のファイルは,末尾が“.save”で終わる名前に変えられます.末尾が“.save”で終わる名前のファイルがすでに存在する場合は,ソースファイルは破棄されてしまいます.

 以下に単純な変換の例を示します.

  $ cat test42.c
  test()
  {
   char a;
   a='a';
  }
  $
  $ protoize test42.c
  protoize: compiling `test42.c'
  protoize: converting file `test42.c'
  $ cat test42.c
  test(void)
  {
   char a;
   a='a';
  }
  $

 ANSIの規約では,引き数がない場合には“void”をつけることになっています.関数の引き数を変換した例です.

 リスト23リスト24の例は「プロトタイプ宣言」を挿入する例です.このように「プロトタイプ宣言」を挿入し,関数宣言の形式も変更してしまいます.ただし,現在のCの記法ではこういった方法をとらないように思えます.リスト25のように「プロトタイプ宣言」を挿入し,関数宣言もこのようにしたほうがわかりやすいように思えます.

〔リスト23〕プロトタイプ宣言のないソース(実行前test43.c)
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
typedef struct t_mutex
{
    int             flag;
    pthread_mutex_t mutex;
} _mutex;
main()
{
    int res;
    _mutex  info;
    res =   thread_mutex_create(&info);
}
int thread_mutex_create(_mutex *mutex_info)
{
    int result;
    pthread_mutex_t buf;
    result  = pthread_mutex_init(&(mutex_info->mutex),0);
    if  (   result  ==  0   )
    {
        return  0;
    }
    else
    {
        return  -1;
    }   
}

〔リスト24〕protoizeで処理したソース(実行後test43.c)
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
typedef struct t_mutex
{
    int             flag;
    pthread_mutex_t mutex;
} _mutex;

int thread_mutex_create ();

main(void)
{
    int res;
    _mutex  info;
    res =   thread_mutex_create(&info);
}
int thread_mutex_create(mutex_info)
     _mutex *mutex_info;
{
    int result;
    pthread_mutex_t buf;
    result  = pthread_mutex_init(&(mutex_info->mutex),0);
    if  (   result  ==  0   )
    {
        return  0;
    }
    else
    {
        return  -1;
    }   
}

〔リスト25〕筆者の考えで修正したソース(test43.c)
#include <stdio.h>
#include <pthread.h>
#include <sched.h>
typedef struct t_mutex
{
    int             flag;
    pthread_mutex_t mutex;
} _mutex;

int thread_mutex_create(_mutex *mutex_info);

main(void)
{
    int res;
    _mutex  info;
    res =   thread_mutex_create(&info);
}
int thread_mutex_create(_mutex *mutex_info)
{
    int result;
    pthread_mutex_t buf;
    result  = pthread_mutex_init(&(mutex_info->mutex),0);
    if  (   result  ==  0   )
    {
        return  0;
    }
    else
    {
        return  -1;
    }   
}

 もっとも,この件に関してはプログラマの好みの問題です.通常は,protoizeを使わないで最初からプロトタイプ宣言を挿入してコーディングしたほうがメンテナンス性が高まると思います.

*          *

 次回はGCCのインストールに関して,またGCCの拡張機能について,説明と検証を詳細に行う予定です.

NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
クロスコンパイル環境について
コード生成規約に対するオプション
実行に影響を与える環境変数
◆プログラムにプロトタイプを追加するprotoizeについて, またプロトタイプを削除するunprotoizeについて

Copyright 2003 岸 哲夫

Copyright 1997-2017 CQ Publishing Co.,Ltd.