În articolul pe care îl prezentăm, ne vom adânci în lumea fascinantă a lui SQLite și vom explora importanța sa în societatea actuală. SQLite este un subiect care a captat atenția experților și entuziaștilor deopotrivă, generând dezbateri interesante și pasionale. De-a lungul anilor, SQLite și-a dovedit influența asupra diferitelor aspecte ale vieții de zi cu zi, de la tehnologie la cultura populară. În acest articol, vom explora fundalul SQLite, evoluția sa în timp și impactul său asupra lumii moderne. În plus, vom analiza diferitele perspective și opinii despre SQLite, cu scopul de a oferi o viziune cuprinzătoare și obiectivă asupra acestui subiect foarte relevant.
Tonul acestui articol sau al acestei secțiuni este nepotrivit pentru o enciclopedie. Puteți contribui la îmbunătățirea lui sau sugera modificările necesare în pagina de discuție. |
SQLite | |
Dezvoltator | D. Richard Hipp |
---|---|
Versiune inițială | august 2000 |
Ultima versiune | 3.47.2[1] () |
Repo | sqlite.org./docsrc |
Scris în | C |
Sistem de operare | Multiplatformă |
Mărime | 658 KiB |
Tip | RDBMS (embedded) |
Licență | Domeniu public[2] |
Prezență online | |
sqlite.org | |
Modifică date / text |
SQLite (pronunțat în engleză /ˌɛskjuːɛlˈlaɪt/[3] sau pronunțat în engleză /ˈsiːkwəl.laɪt/[4]) este o mică bibliotecă C care implementează un motor de baze de date SQL încapsulat. Oferă posibilitatea de a-l introduce în diverse sisteme și necesită zero-configurare.
SQLite este o mică bibliotecă C care implementează un motor de baze de date SQL încapsulat, oferă posibilitatea de a-l introduce în diverse sisteme și necesită zero-configurare. Caracteristicile includ:
Distribuția SQLite vine cu un program linie-comandă de sine stătător (sqlite) care poate fi folosit pentru a administra o bază de date SQLite și care servește că un exemplu despre modul în care să folosiți librăria SQLite.
SQLite este diferit de majoritatea altor motoare de baze de date SQL prin aceea că a fost proiectat pentru a fi simplu:
Multora le place SQLite deoarece este mic și rapid. Dar aceste calități sunt doar accidente fericite. Utilizatorii descoperă, de asemenea, că SQLite este foarte sigur. Siguranța este o consecință a simplismului. Cu mai puțină complicare, este mai puțin loc de greșeli. Deci, da, SQLite este mic, rapid și de încredere (sigur), dar în primul rând și cea mai mare calitate a lui este aceea că reușește să fie simplu. Simplitatea într-un motor de baze de date poate fi fie un punct tare, fie unul slab, depinde de ceea ce încerci să faci. Pentru a atinge simplitatea, SQLite a trebuit să sacrifice alte caracteristici care sunt găsite de unii oameni folositoare, ca cea a concurenței înalte, controlul la accesul detaliat, un set bogat de funcții implementate, proceduri stocate, caracteristici ezoterice a limbajului SQL, extensii XML și/sau Java, scalabilitate tera- sau peta-octet și așa mai departe. Dacă ai nevoie de unele din aceste caracteristici și nu îți pasă de complexitatea adugată pe care o aduc, atunci SQLite nu este probabil baza de date de care ai nevoie. Nu este proiectat să concureze cu Oracle sau cu PostgreSQL.
Regula de bază pentru când este potrivit să folosim SQLite este aceasta: folosește SQLite în situații unde simplitatea în administrare, implementare și întreținere sunt mai importante decât nenumăratele caracteristici complexe pe care motoarele de baze de date enterprise le furnizează. După cum se dovedește, situațiile unde simplitatea este o alegere mai bună sunt mai des întâlnite decât realizează mulți oameni.
SQLite de obicei va merge formidabil ca bază de date pentru trafic al siturilor web mic spre mediu (care este, să spunem, 99.9% din toate siturile). Cantitatea de traffic web pe care SQLite îl poate administra depinde, binențeles, de cât de mult folosește situl web baza de date. În general, orice sit care primește mai puțin de 100000 de vizite/zi ar trebuii să meargă bine cu SQLite. Cele 100000 de vizite/zi sunt o estimare conservativă, nu o limită maximă. SQLite a fost demonstrat că merge și cu de 10 ori această cantitate de trafic.
Deoarece o bază de date SQLite necesită puțină (sau deloc) administrare, SQLite este o alegere bună pentru dispozitive sau servicii care trebuiesc să meargă neadministrate sau fără sprijin uman. SQLite este potrivit pentru a fi folosit în telefoane mobile, PDA-uri și altele. Ar putea merge bine și ca bază de date încapsulată în aplicații consumator descărcabile.
SQLite a fost folosit cu succes ca un fișier pe disc sau aplicații desktop ca de exemplu unealtă de analiză financiară, pachete CAD, programe de ținut înregistrări și așa mai departe. Operația tradițională File/Open efectuează un sqlite3_open() și execută un BEGIN TRANSACTION pentru a obține acces exclusiv la conținut. File/Save face un COMMIT urmat de un alt BEGIN TRANSACTION. Folosirea tranzacțiilor garantează că update-urile la fișierul aplicației sunt atomice, consistente, izolate și durabile (ACID). Declanșatoare temporare pot fi adăugate bazei de date pentru a înregistra toate schimbările într-o tabela de logare (temporară) Undo/Redo. Aceste schimbări pot fi după aceea urmărite când utilizatorul apasa butoanele Undo și Redo. Folosind această tehnică, o implementare pentru un număr de pași nelimitați Undo/Redo poate fi scrisă în surprinzător de puțin cod.
Multe programe folosesc fopen(), fread() și fwrite() pentru a crea și administra fișiere de date în formate proprii. SQLite merge foarte bine că înlocuitor pentru aceste fișiere de date ad hoc.
Pentru programe care au o mulțime de date care trebuiesc mutate sau sortate în diverse direcții, este de obicei mai ușor și mai rapid să încarce datele într-o bază de date SQLite în-memorie și să folosesca query-uri cu JOIN-uri și clauze ORDER BY pentru a extrage datele în formă și ordinea dorită, decât să încerce codarea acestor operații manual. Folosind o bază de date SQL intern în acest mod oferă de asemenea programului o flexibilitatea mai mare de când coloane noi și indici pot fi adăugați fără a recoda fiecare query.
Utilizatorii SQL experimentați pot pune programul linie-comandă sqlite pentru a analiza diferite dataset-uri. Date brute pot fi importate din fișiere CSV (Comma Separated Values - Valori Separate prin Virgulă), după acea datele pot fi tăiate și aranjate pentru a genera o miriadă (un număr foarte mare) de rapoarte scurte. Utilizări posibile includ analiză log-urilor pe un sit, analiză statisticilor sportive, compilarea metricilor programării și analiza rezultatelor experimentale. Poți, binenteles, să faci același lucru cu o bază de date enterprise client/server. Avantajul în folosirea SQLite în această situație este acela că SQLite este mai ușor de configurat și bază de date rezultată este un singur fișier pe care îl poți stoca pe o dischetă, un pen-drive sau un e-mail către un coleg.
Dacă scri o aplicație client pentru un motor de baze de date enterprise, este logic să folosești o structură de bază de date generică care îți permite să te conectezi la multe diferite tipuri de motoare de baze de date SQL. Este și mai logic să faci pasul de a include SQLite în amestecul de baze de date suportate și să legi static motorul SQLite cu clientul. În acest mod programul client poate fi folosit de sine stătător cu un fișier SQLite pentru teste sau pentru demonstrații.
Deoarece este simplu de setat și folosit (instalarea este trivială: doar copiezi SQLite sau executabilul sqlite.exe pe mașină dorită și îl rulezi) SQLite devine un motor de baze de date apt pentru a fi folosit în predarea SQL. Studenții pot ușor crea oricât de multe baze de date doresc și pot trimite cu ajutorul e-mail-ului aceste baze de date către profesor pentru observații sau pentru notare. Pentru studenți mai avansați care sunt interesați în studiat cum este implementat un RDBMS, codul SQLite foarte bine documentat, comentat și modular poate servi că o bază bună. Nu spunem că SQLite este un model exact a cum sunt implementate alte motoare de baze de date, dar un student care înțelege cum funcționează SQLite poate mult mai rapid înțelege principiile operaționale ale altor sisteme. Extensiile experimentale de limbaj SQL Arhitectură simplă și modulară a SQLite face din el o platformă bună pentru prototipizarea de idei și caracteristici noi pentru limbajul bazei de date (experimente).
Dacă ai multe programe client care accesează o bază de date comună peste o rețea ar trebuii să consideri folosirea unui motor de baze de date client/server în locul a SQLite. SQLite va merge peste o rețea de fișiere sistem, dar din cauza latenței asociată majorității fisierelor sistem rețea, performanța nu va fi satisfăcătoare. De asemenea, implementarea blocării a multor fisieresitem rețea (logică) conține bug-uri (și pe Unix și pe Windows). Dacă blocarea fișierului nu merge așa cum ar trebui, este posibil că două sau mai multe programe client să modifice aceeași parte a aceeași bază de date în același moment, rezultând în o corupere a bazei de date. Deoarece această problemă rezultă din bug-uri din implementarea ce stă la bază fisierelor sistem, nu este nimic ce SQLite ar putea face să prevină problema. O bună regulă este aceea că ar trebui să eviți folositea SQLite în situații în care aceeas bază de date va fi accesată simultan de mai multe calculatoare într-un fișier sistem rețea.
SQLite va merge în mod normal bine că bază de date ce sprijină un sit web. Însă dacă situl web este atât de aglomerat încât te gândești să împarți componența bazei de date pe o mașină separată, atunci cu siguranță ar trebui să iei în considerare folosirea unui motor de baze de date client/server în locul SQLite.
Când începi o tranzacție în SQLite (ceea ce se întâmplă automat înainte de orice operație de scriere care nu este într-un explicit BEGIN...COMMIT) motorul are de alocat un bitmap de pagini murdare în fișierul disc pentru a-l ajută la administrarea jurnalului rollback (de revenire). SQLite necesită 256 de octeți de RAM pentru fiecare 1Mo de bază de date. Pentru baze de date mai mici, cantitatea de memorie necesară nu este o problemă, dar când bază de date începe să crească în rangul mulți-gigaocteți, mărimea bitmapului poate deveni foarte largă. Dacă trebuie să depozitezi și să modifici mai mult de câteva duzini de Go de date, atunci ar trebui să te gândești să folosești un motor de baze de date diferit.
SQLite folosește lacăte reader/writer pe întregul de date. Orice proces citește din orice parte bazei de date, toate celelalte procese sunt oprite din orice punct a bazei de date. Similar, oricând un proces scrie date, toate celelalte procese sunt oprite din citit orice parte a bazei de date. Pentru multe situații nu este o problemă. Fiecare aplicație face propria operație peste de date lucreaza rapid și trece mai departe, nici o închidere nu durează mult de câteva milisecunde. Sunt unele aplicații, însă, care necesită mai multă concurență, și acele aplicații ar avea nevoie de abordări diferite.
Aratăm în continuare unele din caracteristicile SQLite-ului care sunt neobișnuite și care fac SQLite diferit de multe alte motoare de baze de date SQL:
SQLite nu are nevoie de "instalare" înainte de a fi folosit. Nu există procedura de "setup". Nu există nici un proces server care necesită pornire, oprire sau configurare. Nu este nevoie de un administrator pentru a crea o nouă instanță de bază de date sau pentru a atribui permisiuni de acces utilizatorilor. SQLite nu folosește fișiere de configurare. Nu trebuie făcut nimic pentru a atenționa sistemul că SQLite rulează. Nici o acțiune nu este necesară pentru a recupera ceva după o cădere de sistem sau după o pană de curent. Nu este nimic de rezolvat.
Alte motoare de baze de date cunoscute rulează formidabil odată ce le-ai pus pe picioare, însă instalarea inițială și configurarea poate fi intimidant de complexă.
Majoritatea motoarelor de baze de date SQL sunt implementate că un proces server separat. Programe care doresc acces la bază de date comunică cu serverul folosind un fel de comunicare interprocese (tipic TCP/IP) pentru a trimite cereri către server și să primească înapoi rezultate. SQLite nu lucrează așa. Cu SQLite, procesul ce dorește să acceseze bază de date citește și scrie direct din fișierele bază de date de pe disc. Nu există nici un proces server intermediar.
Sunt avantaje și dezavantaje în a lucra fără server. Marele avantaj este acela că nu există un proces server de instalat, setat, configurat, inițializat, administrat și reparat. Acesta este unul din motivele pentru care SQLite este un motor de baze de date "zero-configurare". Programe care folosesc SQLite nu necesită suport administarativ pentru a pregăti motorul de baze de date înainte că acesta să fie rulat. Orice program care este capabil să acceseze discul este capabil să folosească o bază de date SQLite.
Pe de altă parte, un motor de baze de date care folosește un server poate oferi o protecție îmbunătățită în aplicații client - pointeri rătăciți în un client nu pot corupe memoria pe server. Și deoarece un server este un proces unic persistent, el este capabil să controleze accesul la bază de date cu o mai mare precizie, permițând o blocare rafinată și concurență îmbunătățită.
Majoritatea bazelor de date SQL sunt bazate pe modelul client/server. Din cele care sunt fără server, SQLite este singură care este știută, de autor, că permite mai multor aplicații să acceseze aceeași bază de date în același timp.
O bază de date SQLite este un singur fișier disc (ordinar) care poate fi plasat (localizat) oriunde în ierarhia directoarelor. Dacă SQLite poate citi fișierul disc atunci poate citi orice din bază de date. Dacă fișierul disc și directorul său sunt writeable (permit scrierea în ele), atunci SQLite poate schimbă orice în bază de date. Fișierele bază de date pot fi ușor copiate pe memory stick-uri USB sau trimise prin e-mail pentru a partajare.
Alte motoare de baze de date SQL tind să stocheze date că o mare colecție de fișiere. Des aceste fișiere sunt în o locație standard pe care numai motorul de baze de date însăși le poate accesa. Această face datele mai sigure, dar însă face mai greoi și accesul. Unele motoare de baze de date SQL oferă opțiunea de a scrie direct pe disc și trecerea, astfel, de fisierul sistem. Această da performanță, dar pentru costul unui setup considerabil și complexitate de administrare.
Când este optimizată pentru mărime, inreaga librărie SQLite cu toate opțiunile activate este mai mică de 225KiO (după măsurarea pe un ix86 folosind utilitarul "size" de pe pachetul compliator GNU). Opțiunile nenecesare pot fi dezactivate în timpul compilarii pentru a reduce mai mult mărimea librării până sub 170KiO (dacă se dorește).
Majoritatea altor motoare de baze de date SQL sunt mult mai mari decât atât. IBM se lăuda că motorul de baze de date recent lansat CloudScape are "numai" un fișier jar de 2MiB - de 10 ori mai mare decât SQLite chiar și după ce este compresat! Firebird se lăuda că, partea lui client are doar 350KiO. Asta este cu 50% mai mare decât SQLite și nici măcar nu conține motorul de baze de date. Librăria DB Berkeley este la Sleepycat este de 450KiO și omite suport SQL, oferindu-i programatorului doar simple perechi cheie/valoare.
Majoritatea motoarelor de baze de date SQL folosesc atribuire statică a tipului de date. Un tip de data este asociat cu fiecare coloană dintr-un tablou și doar valorilor a acelui tip de date particular le este permis să fie stocate în acea coloană. SQLite relaxează această restricție folosind modul de atribuire a tipului de date evident. În acest mod, tipul de date este o proprietate a valorii însăși, nu a coloanei în care valoarea este stocată. SQLite, astfel, permite utilizatorului să stocheze orice valoare de orice tip în orice coloană necontând tipul declarat al acelei coloane. (Sunt niște excepții de la această regulă: O coloană INTEGER PRIMARY KEY poate stoca doar întregi. SQLite încearcă să convearteasca valorile în tipul de date declarat a coloanei când poate.)
Specificațiile limbajului SQL cer alocarea statică a tipului de date. De aceea uni oameni spun că folosirea modului de alocare a tipului de date evident este un bug în SQLite. Autorii SQLite, pe de altă parte, țin să creadă că această este o caracteristică. Autorii spun că alocarea statică este un bug în specificațiile SQL pe care SQLite l-a reparat într-un mod care este compatibil înapoi.
Majoritatea altor motoare de baze de date SQL alocă o cantitate fixă de spațiu de disc pentru fiecare linie în majoritatea tabelelor. Ele utilizează tehnici speciale pentru manevrarea BLOB-urilor și CLOB-urilor care pot fi de o dimensiune foarte variată. Pentru majoritatea tabelelor, însă, dacă declari o coloanasa fie VARCHAR(100) atunci motorul de baze de date va aloca 100 de octeți spațiu pe disc indiferent de cât de multă informație stochezi în acea coloană.
SQLite, în contrast, folosește numai cantitatea de spațiu pe disc necesară să stocheze informația în o linie. Dacă stochezi un singur caracter în o coloană VARCHAR(100), atunci un singur octet de spațiu pe disc este folosit (de fapt doi octeți - este un overhead la începutul fiecărei coloane pentru a-i înregistra tipul de date și lungimea).
Folosirea înregistrărilor de lungime variabila are un număr de avantaje. Se concretizează, evident, în fișiere bază de date mai mici. De asemenea face bazele de date să ruleze mai rapid, de vreme ce este mai puțină informație să fie mișcată de pe și pe disc. Și, această metodă face posibilă lui SQLite să folosească atribuirea tipului de date evident în locul metodei de alocare statică.
Codul sursă a SQLite este proiectat pentru a fi lizibil și accesibil unui programator mediu. Toate procedurile și structurile de date și multe variabile automate sunt comentate cu grijă cu informații utile despre ceea ce fac. Comentariile elevate sunt omise.
Orice motor de baze de date SQL compilează fiecare declarație SQL într-un fel de structură de date internă care este după aceea folosită pentru a indeplini sarcină declarației. Dar, în majoritatea motoarelor SQL acea structură de date internă este o rețea complexă de structuri interconectate și obiecte. În SQLite, formă compilată a declarațiilor este un program scurt în un limbaj-mașină că reprezentare. Utilizatorii bazei de date pot să vadă acest limbaj mașină virtuală prin adăugarea la sfârșitul unui query a keyword-ului (cuvântul rezervat) EXPLAIN.
Folosirea unei mașini virtuale în SQLite a fost de un mare folos dezvoltării librăriei. Mașină virtuală oferă o crispă, o bine definită uniune între front-end-ul SQLite (partea care parsează declarațiile SQL și generează cod mașină virtuală) și back-end-ul acestuia (partea care execută codul virtual mașină și calculează un rezultat). Mașină virtuală permite dezvoltatorilor să vadă clar și în o manieră ușor de citit ceea ce SQLite încearcă să facă cu fiecare declarație pe care o compilează, care este de un ajutor de neimaginat în debugging. Depinzînd de cum este compilat, SQLite de asemenea are capacitatea de a urmării execuția codului mașină virtual - printand fiecare din instrucțiunile mașinii virtuale și rezultatele lor în timpul execuției.
Codul sursă pentru SQLite este în domeniul public. Nu există nici o pretenție de drept de autor pe nici o parte din codul sursă de bază. (Documentarea și codul test sunt o altă problemă - unele secțiuni din documentație și logică testelor sunt guvernate de licențe open-source.) Toți contribuabilii la core-ul SQLite au semnat cum că nu au nici un interes de drept de autor asupra codului. Această înseamnă că oricine este capabil să facă orice vrea cu codul sursă SQLite (legal).
Sunt alte motoare de baze de date SQL cu licențe liberale care permit ca, codul să fie extins și liber folosit, dar acele alte motoare sunt încă guvernate de legea dreptului de autor. SQLite este diferit în aceea că acea lege a dreptului de autor nu i se aplică.
Fișierele de cod sursă pentru alte baze de date SQL încep în mod normal cu un comentariu ce descrie drepturile tale de a copia, vedea sau modifică acel fișier. Codul sursă SQLite nu conține nici o liceenta atât timp cât nu este guvernat de legea dreptului de autor. În schimbul unei licențe codul sursă SQLite oferă o binecuvântare:
Fie să găsești iertare pentru tine și să ierți pe alții
Fie să împarți liber, niciodată luând mai mult decât dai."SQLite oferă un număr de îmbunătățiri limbajului SQL ce nu le găsești în mod obișnuit în alte motoare de baze de date. Cuvântul rezervat EXPLAIN și alocarea tipului de date evident sunt specificate mai sus. SQLite de asemenea oferă declarații că REPLACE și clauza ON CONFLICT care permite control asupra rezolvării conflictelor. SQLite suportă ATTACH și DETACH, comenzi care permit ca mai multe baze de date independente să fie folosite în același query! SQLite definește API-uri care permit utilizatorului să adauge noi funcții SQL secvențe cumulate.
Librăria SQLite implementează majoritatea limbajului SQL standard, însă omite niște caracteristici timp ce adaugă altele, proprii, în același tinp. De asemenea oferă o listă de cuvinte cheie (rezervate limbajului).
Aici afli ce faci pentru a începe să experimentezi SQLite fără a avea de citit sau configurat prea mult:
Descarcă codul
Creează o nouă bază de date
Scrie programe care folosesc SQLite
Dedesubt este un simplu program TCL ce demonstrează cum să folosești interfața TCL pentru SQLite. Programul execută declarațiile SQL transmise ca al doilea argument către baza de date definite de primul argument. Comenzile pentru a vizualiza pentru sunt comanda sqlite3 de pe linia 7 care deschide o bază de date SQLite și creează o noua comandă TCL numită db pentru a accesa aceea bază de date, invocarea comenzii db pe linia 8 pentru a execută comenzile SQL în baza de date și închiderea conexiunii cu baza de date pe ultima linie a scriptului.
#!/usr/bin/tclsh if {$argc!=2} { puts stderr "Usage: %s DATABASE SQL-STATEMENT" exit 1 } load /usr/lib/tclsqlite3.so Sqlite3 sqlite3 db db eval x { foreach v $x(*) { puts "$v = $x($v)" } puts "" } db close
Dedesubt este un simplu program C care demonstrează cum să folosești interfața (mediul) C/C++ pentru SQLite. Numele unei baze de date este dat de primul argument și al doilea argument este una sau mai multe declarații SQL pentru a fi executate în baza de date. Apelurile de funcție la care trebuie să fi atent aici sunt apelul sqlite3_open() pe linia 19 care deschide baza de date, sqlite3_exec() pe linia 25 care execută comenzile SQL în baza de date și sqlite3_close() pe linia 30 care închide conexiunea cu baza de date.
#include <stdio.h> #include <sqlite3.h> static int callback(void *NotUsed, int argc, char **argv, char **azColName){ int i; for(i=0; i<argc; i++){ printf("%s = %s\n", azColName, argv ? argv : "NULL"); } printf("\n"); return 0; } int main(int argc, char **argv){ sqlite3 *db; char *zErrMsg = 0; int rc; if(argc != 3){ fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv); exit(1); } rc = sqlite3_open(argv, &db); if( rc ){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } rc = sqlite3_exec(db, argv, callback, 0, &zErrMsg); if(rc != SQLITE_OK){ fprintf(stderr, "SQL error: %s\n", zErrMsg); sqlite3_free(zErrMsg); } sqlite3_close(db); return 0; }
Versiunea 3.0 a SQLite introduce schimbări importante în librărie, incluzând:
Versiunea 2 a SQLite stochează toate vlorile coloanelor că text ASCII. Versiunea 3.0 îmbunătățește această prin oferirea capacității de a stoca numerele întregi și numerele reale într-un format mai compact și capabilitatea de a stoca date BLOB.
Fiecare valoare stocată în o bază de date SQLite (sau manipulate de motorul de baze de date) are una din urmatoareale clase de stocare:
Că și în SQLite versiunea 2, orice coloană a unei baze de date versiunea 3.0, cu excepția coloanei INTEGER PRIMARY KEY, pot fi folosite pentru a stoca orice tip de valoare.
Toate valorile date lui SQLite, fie că sunt literali încorporați în declarații SQL sau valori legate de declarații SQL precompilate sunt atribuite unei clase de stocare înainte că declarația SQL să fie executată. În condițiile de mai jos, motorul de baze de date poate converti valorile între clasele de stocare numerice (INTEGER sau REAL) și TEXT în timpul execuției query-urilor.
Clasele de stocare sunt inițial atribuite după cum urmează:
Clasă de stocare a unei valori care este rezultatul unui operator scalar SQL depinde de cel mai de la margine operator al expresiei. Funcții definite-utilizator pot întoarce valori cu orice clasă de stocare. Nu este în general posibil să se determine clasă de stocare a rezultatului a unei expresii în timpul compilării.