Včera jsem si zase užil. Do poměrně základního hlavičkového souboru bylo přidáno
#include <gdiplus.h>
a společný build se lehce rozsypal. Zajímavé bylo, že zlobily zásadně starší projekty a chyby byly hlášeny v systémových headerech. Typ chyb byl dvojí.
t:\include\GdiplusImaging.h(22) : error C2065: 'ImageFormatUndefined' : undeclared identifier t:\include\GdiplusImaging.h(22) : error C2501: 'DEFINE_GUID' : missing storage-class or type specifiers t:\include\GdiplusImaging.h(22) : error C2078: too many initializers t:\include\GdiplusImaging.h(23) : error C2065: 'ImageFormatMemoryBMP' : undeclared identifier t:\include\GdiplusImaging.h(23) : error C2501: 'DEFINE_GUID' : missing storage-class or type specifiers t:\include\GdiplusImaging.h(23) : error C2374: 'DEFINE_GUID' : redefinition; multiple initialization t:\include\GdiplusImaging.h(22) : see declaration of 'DEFINE_GUID' t:\include\GdiplusImaging.h(23) : error C2078: too many initializers t:\include\GdiplusImaging.h(24) : error C2065: 'ImageFormatBMP' : undeclared identifier t:\include\GdiplusImaging.h(24) : error C2501: 'DEFINE_GUID' : missing storage-class or type specifiers t:\include\GdiplusImaging.h(24) : error C2374: 'DEFINE_GUID' : redefinition; multiple initialization t:\include\GdiplusImaging.h(22) : see declaration of 'DEFINE_GUID'
příčina je celkem zřejmá, chybí definice makra DEFINE_GUID. Tímto byly postiženy projekty, které vznikly ještě ve Visual C++ 4.2 (nebo dokonce starším). V těch novějších totiž stdafx.h standardně obsahuje
#ifndef _AFX_NO_OLE_SUPPORT #include <afxole.h> // MFC OLE classes #include <afxodlgs.h> // MFC OLE dialog classes #include <afxdisp.h> // MFC Automation classes #endif
což makro DEFINE_GUID definuje. Minimální include pro správné fungování nechávám P.T. publiku jako snadný domácí úkol.
Druhá chyba vypadala následovně
t:\include\GdiplusFlat.h(267) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(270) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(273) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(277) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(281) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(285) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(289) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(293) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(296) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(299) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(302) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(305) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(308) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(312) : error C2955: 'iterator' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\utility(71) : see declaration of 'iterator' t:\include\GdiplusFlat.h(1438) : error C2955: 'map' : use of class template requires template argument list C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\map(140) : see declaration of 'map'
Řádky 266 a 267 souboru GdiplusFlat.h vypadají následovně
GpStatus WINGDIPAPI GdipCreatePathIter(GpPathIterator **iterator, GpPath* path);
shnilého je něco s tím iterátorem. A skutečně, ve všech takto zasažených projektech se někde v jiných hlavičkách vyskytlo
using namespace std;
plus patřičný include headeru STL. A tam skutečně byl zaveden iterator coby templátová třída. V tomto případě bylo správným řešením odstranění tohoto poklesku (spíše zločinu) z patřičných headerů.
using namespace … nemá v hlavičkových souborech co dělat. Nikdy.