2016-08-16 10 views
0

Iが列挙を返す関数ポインタを持っているいくつかの一つはenumを返す関数ポインタにベースアドレスを割り当てる方法は?私の列挙型コードに</p> <pre><code>typedef enum { FIRST, SECOND, THIRD } STATUS; </code></pre> <p>ある<br>

STATUS (*start_port)(void *,void *)= 0x80000001; 

としてベース・アドレスを割り当てることを試みた。しかし、それは警告を投げている

"初期化すると、キャストのない整数からポインタが作成される"

とも

が、私はその後、別の宣言

STATUS (*start_port)(void *,void *); 

を入れてみました "ISO C90は、混合宣言とコード[-Wdeclaration-後のステートメント]を禁じ"次のようにアドレスを関数ポインタに代入する

start_port = (unsigned int *)0x80000001; 

それは混合宣言の警告を修正しますが、新しいエラーは、私がきちんと固定に関数ポインタをカースト入力する方法を知っていただきたいと思い

「互換性のないポインタ型から割り当て」

を思いつきました戻り値が列挙型の場合は、(定数)ベースアドレスを返します。

+2

ですから、呼び出したい関数のコードは、アドレス '0x80000001'で実際にありますか? –

+1

変数 'start_port'は関数へのポインタです。値を正しい型にキャストする必要があります。 –

+1

Re。 c90警告:標準C、つまりC11または少なくとも現代C99を使用します。 **本当に**古いコードを維持しなければmideval C90を使用しないでください。 – Olaf

答えて

1
  1. あなたはタイプの関数ポインタのstart_portを宣言し、それにunsigned int *ポインタを割り当てようとしている、

    STATUS (*start_port)(void *,void *) = (STATUS (*)(void *,void *)) 0x80000001; 
    

    を試みるが、これはひどいなスタイルで、あなたはそれを行うべきではありません。

  2. コード内に変数を宣言しないように警告していますが、これは現代版のでは問題にはなりませんが、IMHOはまだまだ良い方法です。コード内の変数を絞り込むと、アルゴリズムとロジックに従うのが難しくなります。ブロックの先頭でのみ宣言するのでは、コード全体を読みやすくなります。宣言がどこにあるのか知っていて、単に宣言であるコードの部分をスキップする必要はありません。

  3. 同じ問題(1)のように、そのキャストする正しい方法としては、他の回答に記載されている

    start_port = (STATUS (*)(void *,void *)) 0x80000001; 
    
+0

変数の宣言は、可能な限り使用法に近いものでなければなりません(例えば、使用されるループの直前など)。長い関数は、変数の型や変数がどこから来たのかをチェックするために常に上下にジャンプしなければならないときに、混乱する可能性があります。 –

+1

長い関数はすでに混乱しています。長い関数がある場合は、宣言を置く場所以外にも心配することがあります。関数の本体は、少なくともエディタのバッファに収まる必要があります。長ければ、妥当な説明は非常に長い 'switch'文です。さもなければ、変数をどこに宣言しても、バグは非常に簡単です。 –

+0

素早く答えてくれてありがとう本当に私の一日を飾ったのは – achoora

2

である、あなたは関数ポインタに整数に変換するために明示的なキャストを使用する必要があります:

STATUS (*start_port)(void *,void *)= (STATUS(*)(void *,void *))0x80000001; 

しかし、関数ポインタは読みにくいです。それらをよりきれいにするためにtypedefを使用します。

typedef STATUS FuncType(void*, void*); 
    ... 
FuncType * start_port = (FuncType *)0x80000001; 
+0

です。その型の関数が1つしかない場合、 'typedef'にはほとんど使われません。これがジャンプテーブルだと思ってください。 – Olaf

+1

@Olaf 'typedef'は一回の使用でもコードをより明確にします。ポインターの意図された使用法はすぐにわかります。 – user694733

+1

ナンセンス。あなたはまだ2つの場所を確認する必要があります。 'typedef'は複数の関数のインターフェースを変更しようとすると意味があります。しかし、ここではそうではなく、複数の機能(ジャンプ・テーブル)があっても、すべての機能のインタフェースを変更したくない可能性が高いです。とにかくポインタごとに1つの 'typedef'が必要です。 **答え、あなたの答えはどうですか?** – Olaf

関連する問題