Migration VS2010 -> VS2013



  • Hallo,

    Ich habe ein bestehendes MFC Projekt welches ohne Probleme im Visualstudio 2010 kompiliert.

    Jetzt wollte ich den Schritt machen und alles im neuen Visualstudio 2013 kompilieren.

    Leider funktioniert das nicht so leicht wie ich dachte.

    Ich habe das Projekt von VC6 -> VS2005 -> VS2008 -> VS2010 jedesmal ohne größere Probleme migriert bekommen, nur hier beisse ich mir die Zähne aus.

    Ich bekomme folgenden Fehler:

    Fehler 1 error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtr1common 15 1 ProjName

    Nachdem der erste Fehler +- 50mal auftaucht kommt dann dieser:

    Fehler 54 error C2732: Bindungsangaben widersprechen vorheriger Angabe für 'pow' C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtgmath.h 76 1 ProjName

    Der letzte wiederholt sich dann für fast jeder Funktion aus der math.h (cos, ceil, sin, ...)

    Und nach 100 Fehlern bricht er das kompilieren ab.

    Nach einer kurzen Suche im Internet war klar, irgendwo muss ein > extern "C" < zu finden sein.
    Leider nichts.

    Dann habe ich nachgeschaut ob ich irgendwelche ".c" Dateien habe, auch Fehlanzeige.

    Zum Schluss habe ich den Compiler extra noch angewiesen bei".cpp" Dateien wirklich den C++ Compiler zu benutzen.
    Aber auch das brachte keine Besserung.

    Jetzt wende ich mich an euch.

    Wie kann ich dem Fehler auf den Grund gehen und ihn beheben?

    Vielen Dank für eure Hilfe


  • Mod

    Lass Dir mal eine Pre-Compiler Ausgabe machen, evtl. hast Du einen "dummen" define in Deinem Code.



  • Hallo

    Danke für die Antwort.

    Leider weiss ich nicht wie man das macht.

    Gibt es dazu eine Anleitung?


  • Mod



  • Hallo,

    Also in den generierten ".i" Dateien geben sich die > extern "C" < nur so die Klinke in die Hand.

    Wenn ich das allerdings richtig sehe passiert das immer in Dateien die ich nicht in der Hand habe und die zum Basispaket vom Visualstudio gehören.

    Beispiel:

    #line 19 "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\include\\math.h"

    #pragma pack(push,8)

    extern "C" {
    #line 29 "C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\include\\math.h"

    Wie kann ich das kontrollieren oder verändern?



  • Du machst doch C++...

    <cmath> statt <math.h>



  • ~Edit: Doppelpost gelöscht.~


  • Mod

    Und warum bitte extern "C" vor diesen Headern?

    Das macht doch auch keinen Sinn! Wenn es der Compiler braucht muss es in den Headern von selbst gesetzt warden.



  • Hallo,

    zu Caligulaminus

    Ich habe die ganzen standard C header includes ersetzt durch die c... Versionen
    math.h -> cmath
    float.h -> cfloat
    usw

    hat aber auch nichts geändert.

    zu Martin Richter
    Ja gute Frage, ich packe das > extern "C" < nicht dort hin.

    Ich habe mir mal ein paar dieser H dateien angeschaut, meistens kommt das > extern "C" < aus solch einem Block (oder ähnlich)

    #ifdef __cplusplus // [
    #ifndef __nothrow // [
    # define __nothrow __declspec(nothrow)
    #endif // ]
    extern "C" {
    #else // ][
    #ifndef __nothrow // [
    # define __nothrow
    #endif // ]
    #endif /* __cplusplus */ // ]

    Ich kann aber schlecht die standard include Dateien des Visual Studios anpassen.

    MFG


  • Mod

    Doch es gehört dahin. Sorry! Ich war zu schnell.
    Aber scheinbar gibt es bei der Art Deines Projektes widersprüchliche Infos.

    Bleiben wir doch mal bei pow, die Du in Deinem ersten Posting angibst.

    Zeile 76 Microsoft Visual Studio 12.0\VC\include\xtgmath.h:

    float __CRTDECL  pow(_In_ float, _In_ float) _NOEXCEPT;
    

    In math.h Zeile 1115 ist dies ein inline:

    inline float __CRTDECL pow(_In_ float _X, _In_ float _Y) throw()
            {return (powf(_X, _Y)); }
    

    Die Frage wäre für mich:
    1. Ist __CRTDECL evtl. umdefiniert worden? Oder eben unterschiedlich definiert?
    2. Oder gilt das evtl. für _NOEXCEPT?

    Hast Du ein minimales Sample?



  • Ich habe den Programmcode nach __CRTDECL und _NOEXCEPT durchsucht, beides kommt darin nicht vor.

    Ein Umdefinieren schließe ich also auf meiner Seite aus.

    Ein minimales Sample wird schwer werden, das Projekt an sich ist ziemlich gross und Umfangreich.


  • Mod

    Und was sagt die Präprozessor Ausgabe. Sind die Deklarationen denn gleich?



  • Hallo,

    Es hat etwas gedauert Sorry

    So sieht zb alles von pow aus:

    double __cdecl pow( double _X, double _Y);

    inline double __cdecl pow( double _X, int _Y) throw()
    {return (_Pow_int(_X, _Y)); }

    inline float __cdecl pow( float _X, float _Y) throw()
    {return (powf(_X, _Y)); }

    inline long double __cdecl pow( long double _X, long double _Y) throw()
    {return (powl(_X, _Y)); }

    extern "C" double __cdecl pow( double, double);

    extern "C" double __cdecl pow( double, double);

    float __cdecl pow( float, float) throw ();

    long double __cdecl pow( long double, long double) throw ();



  • Hallo,

    Ich habe jetzt noch eine interessante Option im Compiler gefunden: "/showIncludes"

    1> Hinweis: Einlesen der Datei: z:\sourcenet\library\mylgui\mcstring.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\climits
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\limits.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\crtdefs.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\iostream
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\istream
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\ostream
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\ios
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xlocnum
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\cmath
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\math.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\crtdefs.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtgmath.h
    1> Hinweis: Einlesen der Datei: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xtr1common
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(15): error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(20): error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(32): error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden
    1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(51): error C2894: Vorlagen können nicht mit 'C'-Bindung deklariert werden
    ...

    Wenn ich das richtig deute, dann binde ich in der "mcstring.h" die "iostream" ein und diese bindet soweit andere Header ein bis zur "xtr1common".
    Und dann fangen die Probleme an

    Auf diesem Weg müsste dann doch auch das > extern "C" < drum herum gesetzt werden?

    Ich bin dann den Header Dateien nachgegangen. Jede bindet sofort am anfang die nächste Header Datei ein.
    Ich kann aber nirgendwo sehen das ein > extern "C" < gesetzt wird.

    Vielleicht ist das noch ein Ansatz

    Vielen Dank für die Hilfe



  • Erstelle doch mal ein neues Test-Projekt und binde dort dann nur die "mcstring.h" (bzw. "climits") ein - um zu überprüfen, ob es ein genereller Fehler beim VC ist (was ich aber nicht glaube) oder ob doch etwas bei deinem Projekt falsch ist. Bindest du evtl. vor der "mcstring.h" noch andere Header ein oder hast irgendwelche Defines?



  • Hallo,

    Habe ich genau so gemacht und was soll ich sagen, es kompiliert.

    Also muss es doch an meinen Projekteinstellungen oder an einem #define liegen.

    Ich habe daraufhin die Einstellungen beider Projekte verglichen. Und festgestellt das diese gleich sind.

    Nur wie soll ich so ein #define am einfachsten finden?



  • Hallo,

    Nach langem Suchen, glaube ich den Übeltäter gefunden zu haben.

    Ich habe mein Projekt auf ein minimum Reduziert.

    StdAfx.h, StdAfx.cpp, die .rc datei und die ressource.h.
    Es liess sich nicht kompilieren.
    Dann habe ich die fast komplette StdAfx.h Datei kommentiert und es liess sich auf einmal kompilieren.

    Nach ein bisschen versuchen fand ich dann heraus, dass sobald ich eine afx Header Datei (afxwin.h,afxwin.h, ...) einbinde, ich sofort den Fehler hatte.

    Nachdem ich dann nur den Precompiler laufen gelassen habe und die StdAfx.i auseinander genommen habe stellte ich fest dass die winnt.h ein extern C um eine ganze Reihe von andern Headerdateien legt.

    Unter anderem fallen da auch die templates der xtr1common Datei rein.

    Precompiler:

    #pragma warning(push)
    #line 24 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\winnt.h"
    #pragma warning(disable:4201)
    #pragma warning(disable:4214)

    extern "C" {
    #line 30 "c:\\program files (x86)\\windows kits\\8.1\\include\\um\\winnt.h"

    #line 1 "c:\\program files (x86)\\microsoft visual studio 12.0\\vc\\include\\ctype.h"

    Und irgendwann eingeschlossen in diesem extern "C" Block taucht dann das hier auf:

    #line 1 "c:\\program files (x86)\\microsoft visual studio 12.0\\vc\\include\\xtr1common"

    #pragma once

    #pragma pack(push,8)
    #pragma warning(push,3)

    namespace std {

    template<class _T1,
    class _Ret>
    struct unary_function;

    template<class _T1,
    class _T2,
    class _Ret>
    struct binary_function;

    Dann habe ich mir die Original winnt.h Datei angeschaut und das hier gefunden:

    #ifndef _WINNT_
    #define _WINNT_

    #if _MSC_VER >= 1200
    #pragma warning(push)
    #endif
    #pragma warning(disable:4201) // named type definition in parentheses
    #pragma warning(disable:4214) // bit field types other than int

    #ifdef __cplusplus
    extern "C" {
    #endif

    #include <ctype.h>
    #include <winapifamily.h>
    #define ANYSIZE_ARRAY 1

    Da sieht man das die winnt.h die ctype.h in einem extern "C" einbindet.

    Was meint ihr dazu?

    Und wie kann ich das verhindern?

    Die winnt.h Datei werde ich aber hoffentlich nicht anpassen müssen?



  • Hallo,

    Ich denke ich habe es geschafft.

    Das Problem scheint genau das zu sein was ich in meinem letzten Post beschrieben habe.

    Um das zu umgehen habe ich diverse Header einfach früher eingebunden.

    In der stdafx.h binde ich jetzt diese Header ein:

    #include <cmath>
    #include <climits>
    #include <iostream>
    #include <atldef.h>

    Danach hatte ich noch ein paar andere kleine Probleme aber die liessen sich auch ohne weiteres lösen

    Vielen Dank für eure Hilfe


Anmelden zum Antworten