Breaking-Change: In VC-2010 in der STL wird 0 bzw. NULL nicht mehr gültiger Zeiger akzeptiert

Die STL Implementierung wurde klar hinsichtlich „perfect forwarding“ überarbeitet (Siehe C++0x). Allerdings sind dabei auch einige Sachen reingerutscht die dazu führen, dass sich mancher Code nicht mehr kompilieren lässt.

So führen die nachfolgenen Zeilen zu einem Compiler Fehler:

std::pair<void*,void*> p(0, NULL);
// fails with error C2440: 'initializing' : cannot convert from 'int' to 'void *'

Gleiches negatives Ergebnis erhält man, wenn man die folgenden Zeile kompiliert:

vector<void*> v; 
v.insert(v.begin(),NULL);

Der Hintergrund wird hier in dieser Connect Meldung beleuchtet:
https://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair?wa=wsignin1.0

Das Problem ist, das 0 (NULL) sich zwar brav in einen Zeiger umwandeln lässt. 0 (NULL) bleibt aber deshalb dennoch vom Typ her ein int ist wird nicht zu einem Zeiger. Die typensichere Implementierung in der STL führt nun dazu, dass 0 (NULL) nicht als void* akzeptiert wird.

Einzige Lösung und auch mein Rat:
Man verwendet nicht mehr 0 oder NULL, wenn ein NULL-Zeiger gemeint ist, sondern nullptr
Wer Code kompatibel zu VC-2008 und früher halten muss, kann ja in seinen Headern den folgende Definition einführen:

#if  _MSC_VER<1600
const int nullptr = 0;
#endif

Mehr zu perfect forwarding liest man hier:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
http://thbecker.net/articles/rvalue_references/section_07.html

Wie auch aus dem Connect Artikel zu entnehmen ist kann man damit rechnen, dass sich in VC11 alles wieder etwas zurückentwickeln wird. D.h. std::pair und auch die insert Befehle der Container sollen wirde brav 0 aktzeptieren können, wenn Zeiger gemeint sind. Gleiches bekam ich auch über meine Kontakte zur Produktgruppe zu höhren. Aber was VC11 betrifft ist alles sowieso nur Zukunftsmusik und alles noch im dichten Nebel und was wirklich Realität wird  muss man dann wohl erst mal sehen 😉

Nachtrag vom 09.09.2010:
Dravere hat in einem Kommentar auf eine geniale Implementierung für nullptr hingewiesen:
http://www.c-plusplus.de/forum/viewtopic-var-t-is-220511.html
Die ist weitaus besser als meine Definition als const int.

const class
{
public:
  template<class T> operator T*() const {return 0;}
  template<class C, class T> operator T C::*() const {return 0;}
private:
  void operator&() const;
}
nullptr = {};

Bug: VC-2010 MFC CFormView zeichnet Buttons beim Rollen falsch, es erscheinen schwarze Blöcke

In der MFC 10.0 hat sich ein Bug eingeschlichen, der sich unter Windows Vista und Windows 7  bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der DWM verwendet. D.h. nicht wenn Windows klassisch ausgewählt wird.

Wenn auf einen CFormView mehrere Buttons liegen und der CFormView gerollt wird, dann kommt es unter Umständen zu Fehlern beim Neuzeichnen von Buttons. Dies schließt alle Button-Formen ein: Check-Buttons, Radio-Buttons und normale Buttons.

Das Ganze sieht nach dem Rollen in etwa so aus:

Der Text einiger Buttons erscheint nach dem Rollen als schwarze Blöcke. Es kann auch vorkommen, dass nur Teile der Buttons falsch gezeichnet werden.

Um das Problem gezielt nachzuvollziehen habe ich ein kleines Sample gebaut. Man kann durch zwei Schalter den CScrollView gezielt nach oben oder unten Rollen. Beim Rollen nach unten und bei bestimmten Fenstergrößen tritt dann der Fehler auf. Ich habe das Main-Window entsprechend beim Start in der Größe angepasst.

Das Problem liegt in einer Implementierung von WM_PRINTCLIENT in CScrollView (CScrollView::OnPrintClient), die ein Double-Buffering verwendet, dass entweder falsch ist oder sich eben mit der Standardimplementierung eines Dialoges beißt. Auf den ersten und zweiten Blick konnte ich in der Implementierung selbst keinen Fehler sehen. Deshalb vermute ich, dass sich dieses Double-Buffering mit dem auch vorhandenen Double-Buffering in den Standardimplementierungen der Dialogklasse beißt bzw. nicht korrekt berücksichtigt, dass auch Child-Windows neu gezeichnet werden müssen.

Die Lösung ist entsprechend einfach:

  • Man fügt einfach einen Handler für WM_PRINTCLIENT in seiner von CFormView abgeleiteten Klasse ein.
  • Dieser Handler ruft dann nicht die Implementierung der Basisklasse CFormView auf, sondern die Implementierung in CView (CView::OnPrintClient).
...
ON_MESSAGE(WM_PRINTCLIENT,&CScrollDialogMFCView::OnPrintClient)
...

LRESULT CScrollDialogMFCView::OnPrintClient( WPARAM wp, LPARAM lp )
{
  // Bypass the CScrollView::OnPrintClient implementation
  return CView::OnPrintClient(wp,lp);
}

Dieser Fehler ist in keiner der vorhergehenden MFC Versionen vorhanden (auch nicht in MFCNext), weil einfach kein entsprechender Handler vorhanden war..

Es stellt sich wohl bei einigen jetzt die Frage warum dieser Handler eingebaut wurde. Auch die Antwort ist einfach:
Seit Windows Vista wird stark von AnimateWindow Gebrauch gemacht und auch DWM intern scheint des öfteren WM_PRINT/WM_PRINTCLIENT zu verwenden. Entsprechend haben fast alle Klassen in der MFC entsprechende Handler ergänzt bekommen.

Das Sample kann man hier herunterladen: ScrollDialogMFC – VS-2010.
Ich habe in der stdafx.h einen define FIX_CSCROLLVIEW_PROBLEM eingebaut mit dem man den Fix einfach aktivieren und deaktivieren kann.

Bug: CSimpleMap und CSimpleArray führen bei Verwendung von SetAtIndex zu einem Leak

Wieder einmal ein Bug, der seit VC-2005 bekannt ist und in meinen Augen unmöglich als by design abgetan werden darf.

Das Problem ist simpel, wenn man die Funktion SetAtIndex in den Klassen CSimpleMap und CSimpleArray angewendet wird, dann wird für das bestehende Element in der Map oder im Array kein Destruktor aufgerufen. D.h. eine CSimpleMap<CString,…> bzw. ein CSimpleArray<CString> führt mit der Verwendung von SetAtIndex sofort zu Leaks.

Tückisch in reinen ATL Projekten, weil hier der CRT Heap nicht benutzt wird und die Speicherleaks durch die CRT nicht entdeckt werden, weil der Win32 Heap zum Einsatz kommt.

Hier ist der Bug zu finden, inkl. der in meinen Augen korrekten Implementierung:
https://connect.microsoft.com/VisualStudio/feedback/details/298324/csimplemap-setatindex-do-not-call-a-ditructor

Für mich ist besonders diese Antwort äußerst fragwürdig:

CSimpleMap wasn’t really designed to work for types that needed destruction. The docs state it is limited and you should use CAtlMap instead.

Dieser Satz und dieser Hinweis ist in keiner Doku zu finden. Die Doku liest sich ganz anders:
http://msdn.microsoft.com/en-us/library/d1xc3983(VS.100).aspx

CSimpleMap provides support for a simple mapping array of any given type T, managing an unordered array of key elements and their associated values.

Man kann nur raten SetAtIndex nicht zu verwenden, sondern nur SetAt oder den operator[] ❗

MFC-Next 9.0 > MFC 10.0 denn CMFCRibbonPanel::EnableLaunchButton gibt es nicht mehr

Sehr erfreut waren viele C++ Entwickler darüber das es mit der MFC in VC-2008 weiter ging und MFC-Next veröffentlicht wurde. Das ganze wurde dann fest in VS-2008 SP1 integriert. Normalerweise sind wir es gewohnt, dass zur MFC nur Dinge hinzukommen und nichts wegfällt.

Für die MFC 10.0 aus VS-2010 gilt das diesmal nicht: MFC 10.0 < MFC-Next 9.0!

Irgendwie hat es CMFCRibbonPanel::EnableLaunchButton nicht in die MFC 10.0 geschafft, obwohl die Funktion vollständig in der MFC-Next 9.0 implementiert war. Das soll mal einer verstehen 😕 ich jedenfalls nicht!

Diese Funktion sorgt für den kleinen netten Schalter in einem Panel:

Erstaunlicherweise gibt es diese Funktion nun nicht mehr! Wer also 100% Office-kompatible Anwendungen schreiben will ist hier schon mal aufgeschmissen, wenn er das mit MFC 10.0 machen will.
Im Header finden wir diese Funktion noch mit einem #ifdef auskommentiert. Allerdings nützt es nichts diesen #define zu setzen, denn es gibt keine Implementierung und entsprechend keinen Code in der DLL/Library. Ja und in der MFC Doku finden wir die Funktion auch noch.

Und auch dieses Problem war noch in der Beta-Phase bekannt und wurde abgebügelt, wie man in den nachfolgenden Links lesen kann.
http://social.msdn.microsoft.com/Forums/en/vcmfcatl/thread/29ad2859-6341-4ffb-85c2-f5f056a6ca48
https://connect.microsoft.com/VisualStudioJapan/feedback/details/533876/cmfcribbonpanel-enablelaunchbutton?wa=wsignin1.0
Wem es möglich ist, sollte hier bitte Abstimmen und diesen Bug als wichtig kennzeichnen!

Langsam frage ich mich ob es nicht gescheiter gewesen wäre bei MFC-Next 9.0 zu bleiben und mit VS-2008 weiter zu arbeiten.
Tja und so hat die BCG-Library in Verbindung mit VS-2010 auch eine Daseinsberechtigung. Die kann diesen LaunchButton natürlich darstellen.

PS: Auf Nachfrage bei Microsoft bekam ich eine Antwort aber keinerlei Begründung. Jetzt habe ich eine Support-Anfrage dies bzgl. laufen, allerdings mit wenig Hoffnung. 🙁

PPS: (Nachtrag 01.09.2010) Auch der Microsoft Support kann mir dies bzgl. keine Antwort geben aufgrund eines offenen Rechtsstreits. Siehe auch Kommentar von Samsa.

Bug in der MFC von VC-2010 in CImageList::DrawIndirect

Die Funktion CImageList::DrawIndirect der MFC-10

BOOL CImageList::DrawIndirect(CDC* pDC, int nImage, POINT pt, SIZE sz,
    POINT ptOrigin, UINT fStyle = ILD_NORMAL, DWORD dwRop = SRCCOPY,
    COLORREF rgbBack = CLR_DEFAULT, COLORREF rgbFore = CLR_DEFAULT,
    DWORD fState = ILS_NORMAL, DWORD Frame = 0,
    COLORREF crEffect = CLR_DEFAULT);

hat einen massiven Bug: Sie funktioniert einfach nicht.

Der Unsinn, der sich eingeschlichen hat, liegt in der überschriebenen Funktion

BOOL CImageList::DrawIndirect(IMAGELISTDRAWPARAMS* pimldp);

die durch die oben genannte Variante aufgerufen wird. Denn hier cbSize von IMAGELISTDRAWPARAMS nicht mehr in allen Fällen auf einen korrekten Wert gesetzt. Die Folge cbSize enthält Garbage und der Aufruf von ImageList_DrawIndirect geht in die Hose!
Sowohl in VC-2005 als auch VC-2008 wurde in dieser Funktion explizit der cbSize Member überschrieben, je nach dem ob ComCtl 6.0 oder höher von der Anwendung benutzt wird.

Auch das ist ein Bug, denn hierdurch wird evtl. ein korrekt gesetzter cbSize Wert mit IMAGELISTDRAWPARAMS_V3_SIZE (pre IE 5.01 d.h. _WIN32_IE < 0x0501) überschrieben und damit vergrößert vergrößert. Dadurch kann es zu Zugriffsfehlern kommen oder zu unerwünschten Seiteneffekten.
(siehe https://connect.microsoft.com/VisualStudio/feedback/details/322713/bug-in-cimagelist-drawindirect)

Also haben die Entwickler scheinbar die Zuweisung von pimldp->cbSize = sizeof(IMAGELISTDRAWPARAMS) entfernt! Allerdings haben Sie dabei vergessen in der anderen Funktion nun cbSize korrekt zu initialisieren!

Wir haben also wieder mal einen Fall von: Let us fix one thing and break others…

Das Gemeine an der Sache ist, dass dieser Bug noch vor RTM bekannt war:
https://connect.microsoft.com/VisualStudio/feedback/details/543108/bug-in-cimagelist-drawindirect
Nur ist er nicht mehr gefixed worden!

PS: Natürlich fährt die eigene Software mit der MFC-10 auch gegen die Wand, wenn man die CImageList::DrawIndirect(IMAGELISTDRAWPARAMS* pimldp) Variante verwendet und selbst cbSize nicht initialisiert, was ein ordentlicher Entwickler aber sicherlich nicht vergisst! 😉

Wem es möglich ist, sollte bei den beiden Connect Einträgen Abstimmen und diesen Bug als wichtig kennzeichnen!

Achtung: Alle Visual Studio 2010 Express Editionen müssen registriert werden

In den Express Editionen für Visual Studio 2005 und 2008 war es nur nötig die Versionen zu registrieren, die mit dem Online Installer installiert wurden. Die Installationen die mit dem ISO-Image durchgeführt wurden dies nicht nötig.

Das hat sich mit den VS-2010 Express Editions (VS-EE) geändert. Es spielt keine Rolle ob es sich hier um die EE von C#, C++, VB oder eine der anderen verfügbaren Versionen handelt.
Alle diese Versionen müssen registriert werden. Die Laufzeit ohne Registrierung beträgt 30 Tage.

Ich rate dringend dazu, sofort nach der Installation auch die Registrierung durchzuführen. Und wenn es nicht klappt am nächsten Tag gleich wieder zu versuchen. Die Seite funktioniert leider oft genug nicht. So klagen zumindest nicht wenige Benutzer in den Foren.

Infos zur Registrierung hier:
http://www.microsoft.com/germany/express/registration/default.aspx

Download Link für alle Express Editionen (inkl. ISO-Image) hier:
http://www.microsoft.com/germany/express/download/default.aspx

Nachtrag:
Die FAQ ist ziemlich ungenau. Das jedes Produkt einen eigenen Schlüssel braucht habe ich ausprobiert. Aber man benötigt nur einmal eine Nummer für die Registrierung von VC#-2010 EE oder VC++-2010 EE ❗
Man kann ohne weiteres diese Registrierungsnummer auf mehreren Rechnern für mehrere Installationen benutzen (probiert auf Windows XP und Windows 7 Starter). Zumindest bei mir hat das geklappt. Es ist scheint nicht notwendig zu sein jede Version separat auf jedem neuen Rechner wieder zu registrieren ❗

VS-Tipps & Tricks: Kommentare intelligent und einfach umbrechen

 Wer programmiert, der dokumentiert auch. Denke ich zumindest 😀

Ich zumindest habe teilweise Kommentare, die sich über 10 bis zu 100 Zeilen erstrecken. Die sind nah am Code und erklären, oft was die Hintergründe für das gewählte Design und Vorgehen sind.

Leider ist aber der Editor vom Visual Studio kein Word. D.h. absatzweisen Umbruch kennt das Ding nicht und manuell solche Texte inkl. Einrückungen und Listen mit Bindestrichen oder 1., 2., 3. zu formatieren ist etwas was gar keinen Spaß macht. Zudem sind die Kommentar Zeichen // oder * eher lästig als hilfreich beim schreiben.
Und auch VAX muss hier mal passen. Aber! Netterweise gibt e auch andere Addins.

Ich habe vor langer Zeit schon den Comment Reflower  entdeckt. Mit dem ist das Ganze ein Klacks.
Aus dem nachfolgenden Text:

// Dies ist ein Kommentar, den man nicht wirklich hier schreiben
// müsste und der
// eigentlich nichts bedeutet außer
// die Funktionen von einem netten Addin zu zeigen.
// Das
//  1. wirklich Arbeit erspart
//  2. total simpel zu bedienen ist
//  3. für alle VS-Versionen von 2005 über 2008 bis 2010 verfügbar ist.
// Was bei der Formatierung heraus kommt lässt sich sehen.

Wird in Null-Komma-Nichts der folgende Text:

// Dies ist ein Kommentar, den man nicht wirklich hier
// schreiben müsste und der eigentlich nichts bedeutet
// außer die Funktionen von einem netten Addin zu
// zeigen. Das
//  1. wirklich Arbeit erspart
//  2. total simpel zu bedienen ist
//  3. für alle VS-Versionen von 2005 über 2008 bis
//     2010 verfügbar ist.
// Was bei der Formatierung heraus kommt lässt sich
// sehen.

Wer noch mehr Beispiele sehen will, was das Tool leistet findet hier auf der Sourceforge Seite ein Vorher Nacher Pärchen.

Das Addin existiert für alles Visual Studio Versionen ab 2005.
Es kann hier heruntergeladen werden:

PS: Es empfiehlt sich ein Blick auf die Blockdefnition in den Einstellungen. Dort ist oft ein Leerzeichen hinter dem * bzw. // eingetragen. Leider lässt sich in meiner Version hier RegEx nicht einschalten. Wer also ein <tab>-Zeichen hinter dem * oder // hat wird sich wundern wenn das Addin keinen Kommentar findet. Ich habe das Leerzeichen einfach entfernt…

PPS: Für alle nicht C++ Entwickler. Das Tool funktioniert auch für VB und C# ❗

Tipps & Tricks: VS-2010 Hilfe aufbohren

Microsoft ist es wirklich gelungen in zwei großen Schritten die VisualStudio Online Hilfe bzw. MSDN Integration von einem brauchbaren Tool in VC6, über VS-2003/5/8 wo es gerade auszuhalten war, in VS-2010 zu einem Ding zu verwandeln, bei dem mir fast die Worte fehlen.
Man schmeiße alle Funktionen des Hilfe-Viewers weg und behalte gerade die F1-Taste… alle Vorteile, die mir als Vorteile verkauft werden (keine separate Installation, alles im gewohnten Browser etc. siehe Video unten), sehe ich nicht als Vorteile gegenüber den Nachteilen, die in Kauf genommen wurden.
Ein vielleicht hartes Urteil, aber es geht seit Jahren in dieser Beziehung leider nur bergab.
– Just my 2 cents – 🙁

Das Erste was ich sofort vermisst habe war in der folgenden Reihenfolge:

  1. Dynamic Help
  2. Table of contents (TOC)
  3. Sync to TOC
  4. Index
  5. Filter
  6. Direkte Suche in VS, oder dem entsprechenden Viewer

Ich bin dann auf im Internet auf die Suche gegangen und wurde mit 2 Tools fündig, die einem hier helfen können:

HelpViewerKeywordIndex

Aber wie angekündigt soll es auch hier Verbesserungen geben. Und das außerhalb der Wartungszyklen des VS (siehe Video unten mit Ryan Linton). Zumindest was den Index betrifft und die Suchmöglichkeit innerhalb von VS betrifft schafft ein kleines Tool von Ryan Linton (wie versprochen seit dem 20.04.) wenigstens etwas Abhilfe, der HelpViewerKeywordIndex.

Mit diesem Tool erhält man zumindest mal wieder den Index und ein Suchfenster in VS.
Auch dass das Sucherergebnis in einen VS-Fenster angezeigt werden kann ist nett. Leider betrifft diese Einstellung nicht die Funktion der F1-Taste. In diesem Fall wird immer noch der externe Browser angeworfen und nicht der interne, oder ich habe die Einstellung nicht gefunden wo man mit der F1-Taste ein Browser Fenster in VS öffnet.
Ganz verstanden habe ich auch die Option „Display TOC in page“ nicht.
Das Tool ist zumindest mal ein kleiner Schimmer eines eventuellen zukünftigen Lichtblicks 😉

Aber wer weiß, vielleicht lässt Version 1.1 von  HelpViewerKeywordIndex nicht lange auf sich warten.

H3Viewer

Mit H3Viewer, von meinem MVP-Kollegen Rob Chandler, bekommt man zumindest mal wieder das, was man in VS-2008 auch hatte. Table of Contents, Sync to contents. Und der Viewer ist nicht im Browser. Mit dem Ding lässt sich leben oder zumindest ersetzt es den Viewer den wir aus VS-2005/8 kannten ziemlich gut. Und ja, es gibt auch hier wieder Bookmarks, die jetzt keine Favoriten Einträge im Browser sein müssen 😉
Besonders gefreut habe ich mich auch über die Funktion im Index die Doubletten zum gleichen Stichwort im Index in einem separaten Fenster wieder angezeigt zu bekommen, denn nicht jeder Treffer zu GetWindowtext ist der den ich suche.
Nett auch die TTS Funktion (Text to Speech)
Hier fehlen jetzt eigentlich nur noch die Filter zum vollständigen Glück.

Aber wer weiß, was Microsoft uns demnächst noch zu bieten hat. Laut der Homepage von H3Viewer hat Microsoft noch bereits einige andere Viewer in der Schublade.

Siehe auch:
http://channel9.msdn.com/posts/kmcgrath/Help-30-New-Help-System-in-Visual-Studio-2010/

Links:
http://visualstudiogallery.msdn.microsoft.com/en-us/4af86641-a302-4edf-9853-007bcc670b30
http://mshcmigrate.helpmvp.com/viewer

VS-2010 steht für MSDN Abonnenten sofort zum Download zur Verfügung

Jetzt wird es ernst 😉
Pünktlich wie angekündigt ist VS-2010 RTM in englisch für MSDN Benutzer verfügbar:
http://msdn.microsoft.com/en-us/subscriptions/downloads/default.aspx?pv=18:370

Die entsprechende Trial Versionen können sofort herunter geladen werden:
http://www.microsoft.com/visualstudio/en-us/download

Auch eine Express Version von VC-2010 ist bereits verfügbar:
http://www.microsoft.com/express/Downloads/

Laut Microsoft sollen Übersetzungen in andere Sprachen noch bis Ende diesen Monates auch zur Verfügung stehen.

Der Visual Studio 2010 Release Candidate ist erschienen

Jetzt geht es in die Schlussphase ❗

Der Release Candidate für VisualStudio 2010 ist nun draußen. MSDN Abonnenten können ihn jetzt schon herunterladen. In den nächsten Tagen wird dann auch ein freier Download zur Verfügung stehen.
http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx

Wie auch schon die Beta 2 gibt es für diesen RC eine Go Live Lizenz, mit der man direkt produktiv entwickeln darf.

Das endgültige Erscheinungsdatum bleibt weiterhin der 12. April 2010

PS: Das jetzt der RC erschienen ist, heißt auch, dass nur noch wirklich extrem gravierende Bugs entfernt werden. Mit dem meisten was wir im RC sehen werden wir wohl auch im fertigen Produkt leben müssen. Ich bin gespannt welche Fehler aus der Beta 2 überlebt haben 😉
Dennoch testen und Fehler melden: https://connect.microsoft.com/VisualStudio?wa=wsignin1.0