2

Cライブラリ関数を書いたのですが、関数内では正しいのに戻り値が間違っているようです。

関連するコードは次のとおりです。

(dcml_private.c 内) 問題のある関数:

dcml_status _dcml_get_status(struct dcml_device *dev)
{
    uint64_t data;
    dcml_status ret;
    int len;

    libusb_bulk_transfer(dev->handle,
                     DCML_ENDPOINT | LIBUSB_ENDPOINT_IN,
                     (unsigned char *) &data,
                     DCML_REPORT_SZ, &len, RX_TIMEOUT);

    printf("data = %ld\n", data);

    if (len != DCML_REPORT_SZ)
        printf("DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;

    ret = data & ~(1>>17);
    return (ret);
}

呼び出し関数:

void _dcml_cmd(dcml_context *ctx, dcml_cmd cmd,
      dcml_status quit_cond, int dur)
{
    struct timeval start;
    struct timeval cur;
    uint32_t stat;

    (void)gettimeofday(&start, NULL);
    (void)gettimeofday(&cur, NULL);
    _dcml_send_cmd(ctx->active, cmd);

    while(difftimeval(cur, start) < dur) {
            sleep(POLL_PERIOD);
            stat = _dcml_get_status(ctx->active);

            printf("status (%d), quit_cond (%d)", stat, quit_cond);
            if (stat == quit_cond)
                  break;

            (void)gettimeofday(&cur, NULL);
    }

    _dcml_send_cmd(ctx->active, CMD_NONE);
}

ご覧のとおり、関数内に print ステートメントがあります。_dcml_cmd では、その print ステートメントの典型的な出力は次のようになります。

status (65535), quit_cond (2048)

_dcml_get_status が出力する場所:

data = 128

これが意味することは、戻り値は_dcml_get_statusを終了する直前には正しいが、呼び出し元の関数に戻った直後は正しくないということです(ここでは常に65535の値を持っています...)

「dmcl_status」が列挙型であることを知っておくと役立つでしょう。戻り値の型を uint16_t に切り替えても問題は解決しません。オーバーフローの問題か何かかと思ったのですが、型の変更、明示的なキャスト、マスク行の追加をしても直りません。

何かご意見は?

4

1 に答える 1

8

これは、if ステートメントの後に常に { } を置かないという悪い習慣があるためです。

   if (len != DCML_REPORT_SZ) {
        printf("DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;
   }

fprintf(stderr,...エラーをダンプするためにも使用します。エラーを printf に送信するのは悪い習慣です:

   if (len != DCML_REPORT_SZ) {
        fprintf(stderr, "DCML: LIBUSB ERROR (%s)\n", libusb_error_name(len));
        return STATUS_UNKNOWN;
   }

呼び出し関数には、次のような同じ問題があります。

       printf("status (%d), quit_cond (%d)", stat, quit_cond);
        if (stat == quit_cond)
              break;

使用する:

       fprintf(stderr, "status (%d), quit_cond (%d)", stat, quit_cond);
        if (stat == quit_cond) {
              break;
        }

はい、余分な行を使い果たしますが、ロジックを壊さない場所に fprintfs を追加してこれをデバッグしているときに、午前 3 時にそれをやめてください。:^)

于 2013-06-07T04:51:23.057 に答える