MSVC: ошибка компилятора в на первый взгляд тривиальном коде C? - PullRequest
0 голосов
/ 07 июня 2011

Вот простое 45-строчное консольное приложение , которое воспроизводит ошибку в моей 32-битной системе Win XP.

Соответствующие части:

input_watcher_wndproc принадлежитв окно, которое было настроено через RegisterRawInputDevices для просмотра необработанных событий ввода с клавиатуры.

  LRESULT APIENTRY
  input_watcher_wndproc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) {
    switch(umsg) {
    case WM_INPUT:
      analyze_raw_input((HRAWINPUT)lparam);
      DefWindowProc(hwnd, umsg, wparam, lparam);
      return 0;
    }
    return DefWindowProc(hwnd, umsg, wparam, lparam);
  }

  void analyze_raw_input(HRAWINPUT raw_input) {
    RAWINPUTHEADER header;
    UINT size;
    GetRawInputData(raw_input, RID_HEADER, &header, &size, sizeof(RAWINPUTHEADER));
    printf("raw input device handle: %d\n", header.hDevice);
  }

При компиляции с MSVC 9 или 10 программа всегда неправильно сообщает дескриптор устройства как «1».

Однако, если я применю некоторые, казалось бы, нефункциональные изменения, такие как преобразование оператора switch в оператор if ...

    if (umsg == WM_INPUT) {
      analyze_raw_input((HRAWINPUT)lparam);
      DefWindowProc(hwnd, umsg, wparam, lparam);
      return 0;
    }

... или при добавлении произвольной инструкции передвызов analyze_raw_input ...

  switch(umsg) {
   case WM_INPUT:
     puts("foo");
     analyze_raw_input((HRAWINPUT)lparam);
     DefWindowProc(hwnd, umsg, wparam, lparam);
     return 0;
   }

... код работает нормально и выводит дескриптор устройства corrent.

Вот измененный рабочий исходный код , только с добавленным оператором print.

Есть идеи, что может вызвать такое поведение?

1 Ответ

2 голосов
/ 07 июня 2011

Перед вызовом GetRawInputData обязательно инициализируйте 'size' размером sizeof (RAWINPUTHEADER), поскольку это параметр __inout.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...