Visual Studio compilator (începe), myblog

Aceasta este doar o schiță

Luați în considerare următorul exemplu simplu al unei aplicații consola Windows care imprimă toți parametrii care au trecut prin linia de comandă și variabilele de mediu (envp este un pointer la un șir care conține variabile de mediu cu valorile separate de un semn egal (=)):







.Fișierul bat care compilează acest exemplu are forma:

Aceasta presupune următoarea locație a fișierului

Visual Studio compilator (începe), myblog

Toate aplicațiile Windows trebuie să aibă o funcție de intrare. pentru implementarea cărora sunteți responsabil (ă). Există două astfel de funcții:

_tWinMain și _tmain sunt de fapt macro-uri care se deschid ca WinMain sau wWinMain pentru _tWinMain și main sau wmain pentru _tmain, în funcție de utilizarea Unicode sau nu.

De fapt, sistemul de operare nu apelează funcția de intrare. În schimb, acesta invocă funcția de pornire din biblioteca C / C ++. opțiunea -entrie: linie de comandă. Se inițializează biblioteca C / C ++ astfel încât să puteți apela funcții precum malloc și gratuit. și oferă, de asemenea, crearea corectă a oricăror obiecte C ++ declarate globale și statice înainte de începerea execuției codului. Următorul tabel arată în ce cazuri sunt implementate unele dintre funcțiile de intrare.

Tipurile de aplicații și funcțiile de intrare corespunzătoare

Linkerul este responsabil pentru selectarea funcției de pornire corespunzătoare din biblioteca C / C ++ atunci când se leagă executabilul. Dacă este specificat cheia / SUBSYSTEM: WINDOWS. linkerul caută funcția WinMain sau wWinMain în cod. Dacă aceste funcții nu sunt prezente, linkerul raportează o eroare de "simbol extern nerezolvat". În caz contrar, linkerul selectează WinMainCRTStartup sau wWinMainCRTStartup, respectiv.

În mod similar, dacă este specificat comutatorul / SUBSYSTEM: CONSOLE. linker-ul cauta functia principala sau wmain din cod si selecteaza fie mainstreamCRTStartup, fie wmainCRTStartup, respectiv; dacă nu există nici o valoare principală sau o valoare a codului, este raportată aceeași eroare - "simbol extern nerezolvat".

Dar nu mulți oameni știu că în proiect nu puteți specifica link-ul / SUBSYSTEM deloc. Dacă faceți asta, linkerul va determina subsistemul pentru aplicația dvs. Atunci când se leagă, va verifica care dintre cele patru funcții (WinMain, wWinMain, main sau wmain) este prezentă în codul dvs. și pe baza acestora selectați subsistemul și funcția de pornire din biblioteca C / C ++.

Acum câteva note despre fișierul .bat și cheile de compilator și linker

Când creați un fișier .bat, trebuie să vă asigurați că fișierul text generat are un format pentru a completa o linie în stilul Windows sau Unix. dar nu Mac. în caz contrar, fișierul bat pur și simplu nu va porni.







Pentru funcționarea normală a compilatorului, înainte de a apela cl.exe sau link.exe, trebuie să apelați apelul "% vc_path% vcvarsall.bat" x86. Acest fișier bat inițializează variabilele de mediu INCLUDE. LIB. LIBPATH. PATH și alte câteva necesare pentru activitatea cl.exe și link.exe. De exemplu, în cazul meu a fost

Următoarele chei au fost utilizate atunci când sunați cl.exe:

  • / c - compilație fără legare
  • / ZI - compilatorul include informații de depanare în baza de date a aplicației (numai pentru x86)
  • / nologo - Suprimarea afișării informațiilor despre compilator
  • / W3 - stabilește nivelul avertismentelor compilatorului la nivelul 3
  • / Od - dezactivează optimizarea (pentru că / Od previne mișcarea codului, setarea acestei chei simplifică depanarea)
  • / Oy - împiedică crearea pointerilor de cadru din stiva apelurilor, / Oy - dezactivează acest comportament (numai pentru x86)
  • / D "_DEBUG" - definită la compilarea cu chei / LDd, / MDd și / MTd
  • / D "_WINDOWS" - specifică faptul că OS-ul țintă este Windows
  • / D "UNICODE" - spune compilatorului să utilizeze funcțiile API Win API pentru a lucra cu Unicode
    De exemplu, aici este un fragment din WinUser.h. Asta este, dacă specificăm / D "UNICODE" atunci când compilam, și în codul nostru numim CreateWindowEx. apoi, de fapt, există un apel la CreateWindowExW
  • / D "_UNICODE" - similar cu UNICODE, indică utilizarea în aplicație a versiunilor de funcții din biblioteca C pentru a lucra cu șiruri de caractere Unicode. De exemplu, în fișierul header TChar.h, puteți găsi definiția următoarei macrocomenzi: Acum, când sunați _tcslen și specificați _UNICODE, apelul este rezolvat în wcslen. altfel, în strlen. Implicit în proiectele noi C ++, Visual Studio definește _UNICODE (precum și UNICODE)
  • / Gm - include recompilarea minimă, ceea ce permite recompilarea numai a fișierelor cu cod sursă modificat
  • / EHsc - interceptat numai cu excludere ++ și garantat că funcțiile externe C nu vor elimina niciodată excepția C ++

/ RTC (verificări de eroare de execuție)

/ RTC1 - echivalentul / RTCsu

/ RTCs - Permite verificarea cadrului stivei runtime, ceea ce înseamnă:

  • inițializarea variabilelor locale prin valori non-zero. Acest lucru vă permite să identificați erorile care nu apar în construirea de depanare. Este mai probabil ca variabila din stiva să rămână zero în ansamblul de depanare, mai degrabă decât în ​​ansamblu, deoarece compilatorul optimizează stiva de variabile din ansamblul riei. Odată ce este folosit, memoria stivuită nu este zero de către compilator. Prin urmare, variabilele ulterioare neinstituționalizate din stivă vor conține valorile rămase din utilizarea anterioară a acestei regiuni de memorie.
  • Verificarea fluxului de variabile locale, cum ar fi matrice. / RTCs nu definește un border-out atunci când accesarea memoriei este rezultatul compilatorului aliniind poziția structurii în memorie. Acest lucru se poate întâmpla când se utilizează alinierea (C ++). / Zp sau pack sau, dacă alocați elementele structurii în ordinea în care compilatorul forțează indentarea.
  • Verificarea indicatorului de stivă, care permite determinarea distrugerii indicatorului de stivă. Distrugerea indicatorului de stivă poate apărea dacă tipurile de apeluri nu se potrivesc. De exemplu, utilizând un indicator al funcției, puteți apela o funcție dintr-un DLL exportat ca __stdcall. dar ați definit un pointer la o funcție ca __cdecl.

observaţie:
stack (funcție) - zona de memorie alocată de fiecare dată când o funcție este apelată, este destinată stocării temporare a argumentelor și a variabilelor funcțiilor locale.

/ RTCu - determină compilatorul să emită avertismente atunci când variabila este utilizată fără inițializare. De exemplu, o comandă care generează un avertisment (nivelul 4) C4701 poate genera, de asemenea, o eroare de execuție atunci când este setată tasta / RTCu. Orice comenzi care generează un avertisment de compilare (nivel 1 și 4) C4700. va genera, de asemenea, o eroare de execuție atunci când este setată tasta / RTCu.

Cu toate acestea, luați în considerare următorul fragment de cod:

Afișați navigația

Lasă un răspuns Anulează răspunsul







Trimiteți-le prietenilor: