Problem mit Template



  • Hallo zusammen,

    habe ein Problem mit einem Template. Das Problem ist: der GCC kompiliert problemlos, der MSVC (Visual Studio 2008) meckert:

    template<typename T>
        T GetVarValueFromArray(EVarName var, int Offset, int MaxVal, int ReturnVal);
    
    template <>
    int SimData::GetVarValueFromArray(EVarName var, int Offset, int MaxVal,
            int ReturnField) {
        long val = 0;
        int outVal[MaxVal];
    
        val = XPLMGetDatavi(map_refs[var], outVal, Offset, MaxVal);
    
        return outVal[ReturnField];
    }
    
    template<>
    float SimData::GetVarValueFromArray(EVarName var, int Offset,
            int MaxVal, int ReturnVal) {
        long val = 0;
        float outVal[MaxVal];
    
        val = XPLMGetDatavf(map_refs[var], outVal, Offset, MaxVal);
    
        return outVal[ReturnVal];
    }
    
    \src\simdata\simdata.h(163) : error C2057: expected constant expression
    \src\simdata\simdata.h(163) : error C2466: cannot allocate an array of constant size 0
    \src\simdata\simdata.h(163) : error C2133: 'outVal' : unknown size
    

    Mir ist aufgefallen das der MSVC die Funktion auch in Quelldateien kompilieren will die zwar die "simdata.h" inkludieren, die eigentliche Templatefunktion aber gar nicht aufrufen. Was dann wiederum den Compilerfehler erklärt weil ja die Parameter für die Funktion fehlen.

    Der Fehler "expected constant expression" bezieht sich auf den "MaxVal" Parameter der ja die Grösse des Arrays für "outVal" festlegt.

    Vielleicht hat ja jemand eine Idee warum der GCC zufrieden damit ist und der MSVC nicht?



  • GCC kann Arrays freier anlegen und ist nicht auf Compilezeitkonstante Größen und Nichtnull als Größe festgelegt. Damit weicht GCC vom Standard ab und bietet mehr an.
    http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
    http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html#Zero-Length



  • Danke für den Hinweis. Hab's jetzt für den MSVC "umgebogen", kompiliert schonmal, ob's läuft weiss ich in ein paar Minuten...

    #ifdef _WIN32_
    template <>
    int SimData::GetVarValueFromArray(EVarName var, int Offset, int MaxVal,
            int ReturnField) {
        long val = 0;
    
    	int *outVal;
    	outVal = new int(MaxVal);
    
    	val = XPLMGetDatavi(map_refs[var], outVal, Offset, MaxVal);
    
    	int retVal = outVal[ReturnField];
    	delete[] outVal;
        return retVal;
    }
    #endif
    


  • Warum machst dus nur fürn MSVC so? später kommt dann ein anderer Compiler und kannst auch nicht, danach dann der dritte Compiler... Versuch doch einfach eine standardkonforme Implementierung zu machen, ohne die Zusatzfeatures einzelner Compiler auszunutzen. Wenn du dann später die Performance optimieren musst und die Lösung mit den VLA vom gcc besser ist, kannst du das #ifdef für den GCC machen, statt andersrum.

    template <>
    int SimData::GetVarValueFromArray<int>(EVarName var, int Offset, int MaxVal, int ReturnField) 
    {
        std::vector<int> outVal(MaxVal); //std::vector hat das delete automatisch drin-> Exceptionsicher!
    
        long val = XPLMGetDatavi(map_refs[var], &outVal[0], Offset, MaxVal);
        if (/* val zeigt Fehler an */) 
        {
           /* behandle Fehler. Fehlercodes sollt man nicht ignorieren! */
        }
        return outVal[ReturnField];
    }
    


  • @schwudde, außerdem war deine gepostete Lösung falsch:

    outVal = new int(MaxVal);
    
    ...
    
    delete [] outVal;
    

    Na, siehst du den Fehler???

    Also besser gleich std::vector nehmen (so wie pumuckl schon vorgeschlagen hat).


Anmelden zum Antworten