Компилятор VC ++ не может поймать несоответствие типа HANDLE и PHANDLE - PullRequest
3 голосов
/ 13 октября 2011

Я потратил целый день на поиск ошибки, вызванной неправильной передачей типа Windows PHANDLE функции, ожидающей HANDLE !!! Я ожидал, что компилятор VC ++ 2010 обнаружит такую ​​простую и очевидную ошибку несоответствия типов. Однако это не так. Просто нет.

При ближайшем рассмотрении HANDLE определяется как указатель void в winnt.h, и поэтому PHANDLE - просто указатель void указателя. Поскольку все может быть передано в void * или void **, компилятор не может предупредить несоответствие PHANDLE и HANDLE.

Есть ли способ избежать такой проблемы? Я не знаю, сколько других типов Windows определены как void *. Существуют ли стратегии, позволяющие избежать подобных ошибок?

Например, следующее компилируется без ошибок в VC ++ 2010, хотя функция вызывается с неверными типами указателей. И, это не очевидно, подводная лодка существует, если только вы не знаете, что HANDLE (или любые другие типы Windows) являются пустыми указателями:

void f1 (HANDLE h) {
  printf("%x",h);
}

int _tmain(int argc, _TCHAR* argv[])
{
  PHANDLE ph=NULL;
  int c=0;

  f1(ph);
  f1(&c);
  return 0;
}

1 Ответ

2 голосов
/ 13 октября 2011

Способ представления о HANDLE является базовым типом для всех дескрипторов, таких как HWND, HDC и т. Д. Поскольку C не поддерживает концепцию базового типа, они должны были сделать его void*.

В большинстве случаев ваше приложение должно быть скомпилировано с установленным флагом STRICT. Это гарантирует, что все конкретные дескрипторы на самом деле основаны на структурах, поэтому у вас не возникнет никаких проблем. Однако, если вы напишите метод, который работает с общим HANDLE, вам нужно быть осторожным!

...