1

次のような構造体があります。

struct dgm_network_pkt {
    char    responder[INET_ADDRSTRLEN];
    int     num;
    char    **neighbors;
};

このフィールドnumは、割り当てられて によって指されている文字配列の数を追跡しますneighbors

ここで、ヘッダーと構造体を含むパケットを作成し、このパケットを含む UDP パケットを送信したいと思います。これを実現するには、多くのポインター演算と sizeof() の呼び出しを多数行う必要があります。たとえば、ヘッダーがenum header hdr;、バッファーがchar *buf;、構造体のインスタンスが の場合struct mystruct stc;、次のことを行う必要があります (スニペット):

buf = malloc(sizeof(stc.num * SIZEOF_EACH_ARRAY) + sizeof(hdr) + sizeof(stc.responder) + sizeof(int));

memcpy(buf, &hdr, sizeof(hdr)); /* Copy over header */
memcpy(buf + sizeof(hdr), &stc.responder, sizeof(stc.responder)); /* Copy 'responder' field */
memcpy(buf + dizeof(hdr) + sizeof(stc.responder), &stc.num, sizeof(int)); /* Copy num field */

次に、 が指す文字配列をコピーするループが、同じパラメーターを使用して複数回neighbors呼び出されます。sizeof()

見たい場合は、参照用にこれらすべてを達成するために使用する関数を次に示しますが、私の質問に答える必要はなく、混乱を招く可能性があります (間接的な追加により)。

int dismesh_compose_net_pkt(struct dgm_network_pkt *dismesh_sta, char **buf)
{
    int i;
    int pkt_size;
    enum dgm_header dgm_hdr;

    pkt_size = dismesh_sta->num * DISMESH_ETH_ADDR_STR + sizeof(dgm_hdr) 
        + sizeof(dismesh_sta->responder) + sizeof(int);

    dgm_hdr = NETWORK_STATUS_RESP;
    if ((*buf = malloc(pkt_size)) == NULL)
        return -1; 

    memcpy(*buf, &dgm_hdr, sizeof(dgm_hdr));
    memcpy(*buf + sizeof(dgm_hdr), &dismesh_sta->responder, sizeof(dismesh_sta->responder));
    memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder), &dismesh_sta->num, sizeof(int));

    /* Copy contents of neighbors to buffer */
    for (i = 0; i < dismesh_sta->num; i++) {
        memcpy(*buf + sizeof(dgm_hdr) + sizeof(dismesh_sta->responder) + sizeof(int) + i * DISMESH_ETH_ADDR_STR,
                *(dismesh_sta->neighbors + i), DISMESH_ETH_ADDR_STR);
        DGM_LOG("Packed up neighbor %d\n", i); 
    }   

    return pkt_size;
}

ここにあります:

構造体の内容をバッファにコピーしたり、各要素のサイズなどをコピーしたりする際に、同じパラメータを使用して の呼び出しを何度も使用していることに気付きsizeof()ました。これを行うためのより良い方法はありますか? ヘッダー ファイルにいくつかの #defines を含めることができると考えていました。たとえば、、、、などを行うことができます#define OFFSET_RESPONDER sizeof(hdr)#define OFFSET_NUM OFFSET_RESPONDER + sizeof(mystruct.responder)その#define SIZE_HEADER sizeof(dgm_header)ままにしておくと、パフォーマンスが大幅に低下することに気付きますか? コンパイラ (私の場合は GCC) はこれを最適化しますか? #defines で可読性が低下すると思いますか? このコードをクリーンアップする最良の方法は何ですか?

4

5 に答える 5

2

sizeof()は関数ではなく、コンパイル段階で評価されます。したがって、sizeof(something)by aの多くの出現を変更し#define CONSTANTても、パフォーマンスの観点からは何も変わらないはずです。コンパイル時間のみが変更される可能性がありますが、無視できると思います。

唯一の重要な側面は、コードの読みやすさです。どちらも私にとっては問題ありません、あなたが決めてください。

于 2013-06-28T19:44:30.060 に答える
2

まず、sizeofは関数ではなく演算子であるため、コンパイラはそれを単一の数値に変換します。

次に、offsetofマクロを見てください。私はそれがまさにあなたが必要とすることをすると思います。

于 2013-06-28T19:46:17.643 に答える
1

コンパイラは確かにこれを最適化します。非セマンティックなマジック トークンをあちこちに散らしてコードの可読性を犠牲にすることはありません。

コンパイラの出力をチェックしてこれを確認できますが、いたるところに定数があります。

于 2013-06-28T19:32:41.853 に答える