waarom iostream.h werkt op sommige compilers en niet op andere
Waarom <iostream.h>, <limits.h>, ..., op sommige compilers werken, maar op anderen niet.
Wel, op verschillende compilers werken ze niet, gewoonweg omdat ze dat niet hoeven te doen --- deze headers zijn geen onderdeel van de standaard C++ headers (STL).
Om te kunnen begrijpen waarom deze namen niet werken op de meeste compilers moeten we even teruggaan in de geschiedenis van C++:
Helemaal in het begin van C++, nog voor er ook maar een kladversie van de standaard was, eindigden alle aanbevolen headers op '.h'. Zo zag bijna iedereen zijn eerste programma er als volgt uit:
Code:
#include <iostream.h>
int main()
{
cout << "Hello world!" << endl;
return 0;
}
Wanneer namespaces werden geïntroduceerd in C++ kwam er een nieuwe regel voor de library --- alle namen die door de standaard headers gedeclareerd werden, zouden binnen één namespace gedeclareerd worden, de namespace "std".
Het probleem was dat met deze regel alle bestaande C++ code plots onbruikbaar werd. Zelfs het eenvoudige "Hello world” programma dat zonet werd aangehaald, kon niet meer gecompileerd worden onder deze regel, aangezien cout en endl nu binnen "std" gedefiniëerd zijn. We zouden de hoofdregel als volgt moeten herschrijven:
Code:
std::cout << "Hello world!" << std::endl;
(of een evenwaardige 'using'-constructie gebruiken) op de nieuwere compilers die werkten volgens de std-regel. Maar dan zou de code ook niet meer kunnen gecompileerd worden op de oudere compilers, die nog geen weet van de std-namespace hebben...
Dit zorgde voor een groot probleem: Het is niet mogelijk om code te schrijven die op zowel oudere als niewe compilers werkt!
Er kwam een gedeeltelijke oplossing toen de nieuwe standaardheaders werden uitgebracht. De nieuwe headers zijn diegenen waarin cout en alle andere namen gedeclareerd zijn binnen de standaard namespace.
Schrijvers van compilers werden aangemoedigd om de verouderde .h headernamen ook in hun library op te nemen, om achterwaardse compatibiliteit te voorzien. Zo kan oudere code nog steeds foutloos gecompileerd worden. Volg even mee hoe het in zijn werk gaat:
De standaard-header, die zijn namen binnen std definiëert:
Code:
// <iostream>
namespace std {
class ostream {
// ...
};
ostream cout;
}
De oude .h-vorm van de header is eigenlijk gewoon het inladen van de standaardheader en dan using-definities voor elke naam van de standaardheader. Zo worden de namen bruikbaar zoals in "de goede oude tijd":
Code:
// <iostream.h>
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;
//...
Met dit schema zou het oorspronkelijke "Hello world" gecompileerd kunnen worden zonder aanpassingen, terwijl nieuwe C++ code in de nieuwe regels kan geschreven worden:
Code:
#include <iostream>
int main()
{
std::cout << "Hello world!" << std::endl;
return 0;
}
of, meer voorkomend:
Code:
#include <iostream>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
return 0;
}
--Johan
Deze post is een vrije vertaling van
deze faq-pagina