[VC++] Ce inseamna "unused" intr-o variabila tip HWND?

Mediul de dezvoltare Visual C++, instalare, setari, debugger, compilator, linker si documentatie (forum moderat)
Post Reply
User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

[VC++] Ce inseamna "unused" intr-o variabila tip HWND?

Post by Ovidiu Cucu » 03 Nov 2011, 15:50

Intrebare
Cand expandam o variabila tip HWND in fereastra Watch, QuickWatch sau Variables, apare unused - CXX0030: Error: expression cannot be evaluated, ca in imaginea urmatoare:
HWND value in Watch window.jpg
HWND value in Watch window.jpg (21.93 KiB) Viewed 3393 times
Ce reprezinta aceasta? Este cumva o eroare in program?

Raspuns
Nu, nu este o eroare.
HWND este declarat in Windows SDK dupa cum urmeaza

Code: Select all

DECLARE_HANDLE            (HWND);
iar DECLARE_HANDLE este:

Code: Select all

typedef void *PVOID;
//...
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
typedef HANDLE *PHANDLE;
Dupa preprocesare, rezulta doua cazuri:
  1. Daca STRICT nu este definit, HWND este un alias pentru void*.
  2. Daca STRICT este definit, atunci se obtine ceva de genul:

    Code: Select all

       struct HWND__ 
       {
          int unused;
       };
       typedef struct HWND__ *HWND;
    Deci, in cazul acesta, HWND este de de tip pointer la o structura (HWND__*) care la randul ei are un singur membru dummy numit 'unused', ceea ce se vede in fereasta Watch.
De ce asa?
Daca STRICT nu este definit, deci HWND este de fapt void*, si daca de exemplu se cere ca argument al unei functii, atunci am putea pasa din greseala alt tip de handle, de exemplu HBRUSH, generand erori la run-time.
Daca in schimb, STRICT este definit (default in SDK-ul din Visual C++) atunci se face strict type checking, putind astfel descoperi si corecta eventualele greseli, in faza de compilare.
Exemplu

Code: Select all

   HBRUSH hBrush = ::CreateSolidBrush(RGB(0, 0, 255));
   // ...
   // Stupid mistake but not impossible
   ::SetForegroundWindow(hBrush); 
   // Error: cannot convert parameter 1 from 'struct HBRUSH__ *' to 'struct HWND__ *'
Note
  • La fel sunt definite si alte handle-uri din Windows SDK, cum ar fi HBITMAP, HBRUSH, HINSTANCE, etc.
  • STRICT este definit in Windows SDK by default. Daca din anumite motive nu se doreste strict type checking, se poate scoate, adaugand NO_STRICT la definitiile preprocesor.
Resurse



Viorel
Microsoft MVP
Microsoft MVP
Posts: 286
Joined: 13 Jul 2007, 12:26

Re: [VC++] Ce inseamna "unused" intr-o variabila tip HWND?

Post by Viorel » 04 Nov 2011, 10:16

Ar merge oare fără ‘int unused’? Probabil există un motiv pentru neutilizarea unei structuri fără nici un membru. Se pare că ‘unused’ e adăugat pentru a evita eroarea „C requires that a struct or union has at least one member”.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3776
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: [VC++] Ce inseamna "unused" intr-o variabila tip HWND?

Post by Ovidiu Cucu » 04 Nov 2011, 11:38

In standardul C scrie asa:
ISO/IEC 9899:1999
6.7.2.1 Structure and union specifiers
...
If the struct-declaration-list contains no named members, the behavior is undefined.
Deci, pentru a o folosi in C fara probleme, acea structura trebuie sa aiba macar un membru (dummy).

Post Reply