[C++] bizarre compilatiefout (Visual Studio 2010)

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
Een bepaalde instantie van std::map geraakt niet door de compiler, op zich niet zo speciaal, ware het niet dat wanneer ik dezelfde map (zelfde template args) in een andere, op nodige includes na blanco .cpp file instantieer, het wel goed gaat ...

De map in kwestie, met de nodige typedefs:

C++:
1
2
3
4
typedef const WSSVertex*                            VertexID;
typedef std::tr1::tuple<VertexID,VertexID,VertexID> PolygonSignature;

std::map<SerializedBasePolygon::PolygonSignature, const SerializedBasePolygon*> test;


Ook gek is dat, in de beruchte cpp file waar het mis gaat, volgende map instanties wel door de compiler geraken:

C++:
1
2
3
std::map<int,             const SerializedBasePolygon*>  test1;
std::map<PolygonSignature, SerializedBasePolygon*>      test2;
std::map<PolygonSignature, const int*>                    test3;


cpp file (zie lijn 19) waarin het wel goed gaat, dat ik nu specifiek .begin() aanroep is niet de oorzaak van het plots wel compileren.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdafx.h"
#include "SerializedBasePolygon.h"

#include <iostream>

using std::vector;
using std::cerr;
using std::endl;

vector<XVec3> SerializedBasePolygon::getSubsampled(unsigned int downSamples, std::map<PolygonSignature, const SerializedBasePolygon*>& nbMap) const{

    if(downSamples > mmResolution) {
        cerr << "lowering downsamples to " << mmResolution << endl;
        downSamples = mmResolution;
    }

    vector<XVec3> lowRes;

    nbMap.begin();

    return lowRes;
}


De beruchte source file (zie lijn 22) waarin de map niet door de compiler geraakt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "stdafx.h"
#include "SerializedBasePolygon.h"

#include <iostream>

using std::vector;
using std::cerr;
using std::endl;

vector<XVec3> SerializedBasePolygon::getSubsampled(unsigned int downSamples, std::map<PolygonSignature, const SerializedBasePolygon*>& nbMap) const{

    // OPT: cache the neighbour pointers

    if(downSamples > mmResolution) {
        cerr << "lowering downsamples to " << mmResolution << endl;
        downSamples = mmResolution;
    }

    vector<XVec3> lowRes;

    // get the two side borders ------- hier struikelt de compiler over nbMap
    vector<XVec3> border0 = nbMap[mmNeighbours[1]]->getBorderData(downSamples, mmVertices[0], getBottomLeft());
    vector<XVec3> border1 = nbMap[mmNeighbours[7]]->getBorderData(downSamples, mmVertices[0], mmVertices.back());

    lowRes.push_back(nbMap[mmNeighbours[0]]->getDownSampledCorner(downSamples, mmVertices[0], border0.front()));
    lowRes.push_back(nbMap[mmNeighbours[8]]->getDownSampledCorner(downSamples, mmVertices[0], border1.front()));
    // first row done

    // do the local data except for the last line
    unsigned int localOffset = 0;
    unsigned int localLineSize = 0;
    for(unsigned int borderIndex = 0; borderIndex != border0.size(); ++borderIndex){
        ++localLineSize;
        localOffset += localLineSize;
        lowRes.push_back(border0[borderIndex]);
        lowRes.insert(lowRes.end(), mmVertices.begin() + localOffset, mmVertices.begin() + localOffset + localLineSize);
        lowRes.push_back(border1[borderIndex]);
    }

    lowRes.push_back(nbMap[mmNeighbours[2]]->getDownSampledCorner(downSamples, getBottomLeft(), border0.back()));

    // add the bottom of the local data
    lowRes.insert(lowRes.end(), mmVertices.begin() + calculateNrVertices(1 << mmResolution), mmVertices.end());

    lowRes.push_back(nbMap[mmNeighbours[6]]->getDownSampledCorner(downSamples, mmVertices.back(), border1.back()));


    // add the bottom border data
    lowRes.push_back(nbMap[mmNeighbours[3]]->getDownSampledCorner(downSamples, getBottomLeft(), border0.back()));
    auto bottomborder = nbMap[mmNeighbours[4]]->getBorderData(downSamples, getBottomLeft(), mmVertices.back());
    lowRes.insert(lowRes.end(), bottomborder.begin(), bottomborder.end());
    lowRes.push_back(nbMap[mmNeighbours[5]]->getDownSampledCorner(downSamples, mmVertices.back(), bottomborder.back()));

    return lowRes;
}


De compilatie error komt neer op dat hij geen conversie van const PolygonSignature (een tuple) kan doen naar const WSSVertex* (= VertexID).
Uiteraard kan dat niet, maar ik snap niet hoe hij daar ooit bij zou moeten komen ...
Volledige log: http://pastebin.com/m5c457aec

Ik begin te denken dat er een foutje in de compiler of de std libs van VS 2010 zit, maar met mijn prille kennis van C++ zou ik dat niet zomaar durven zeggen. Zeker omdat in situaties als deze het vroeger steeds mijn eigen fout bleek te zijn. :)

Hebben jullie nog ideeen die kunnen helpen om uit te zoeken waardoor dit veroorzaakt wordt?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hebben jullie nog ideeen die kunnen helpen om uit te zoeken waardoor dit veroorzaakt wordt?
Wat dacht je van je code compilen met een niet-beta compiler zoals VC++ 2008? :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
.oisyn schreef op dinsdag 01 december 2009 @ 15:16:
Overigens, dat de templates in andere versies wel compilen is omdat je niet zelfde members aanroept. Een member function van een template class wordt pas gecompileerd als je 'm gebruikt. Door gewoon zo'n class te instantieren wordt in feite alleen maar de ctor en de dtor gecompileerd (en alles wat daarvoor nodig is), niet operator[] die dan verder niet gebruikt wordt.

Wat intellisense betreft, I wouldn't know, ik gebruik sowieso Visual Assist :)
Ivm de aanroepen, heb ik grondig genoeg getest, daar ligt het niet aan. Het gaat gewoon al, zoals je zegt, om de code die door de ctor wordt getriggerd.

Wel een update:
Ik verander de function args naar (blabla, std::map<PolygonSignature, SerializedBasePolygon*>& nbMap), zonder const dus in de map, en nu gaat dat weer niet, maar een test instantie die wel const heeft in de mapvalue werkt dan weer plots wel.
We hebben dus een nieuwe regel: het type van de map<> die als argument doorgegeven wordt is het probleem. Ik test toch nog maar wat verder dan. Hier gaat niet veel nuttigs meer gecode worden vandaag ...

[ Voor 68% gewijzigd door Bob op 01-12-2009 15:19 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Overigens, dat de templates in andere versies wel compilen is omdat je niet zelfde members aanroept. Een member function van een template class wordt pas gecompileerd als je 'm gebruikt. Door gewoon zo'n class te instantieren wordt in feite alleen maar de ctor en de dtor gecompileerd (en alles wat daarvoor nodig is), niet operator[] die dan verder niet gebruikt wordt.

Wat intellisense betreft, I wouldn't know, ik gebruik sowieso Visual Assist :)

[ Voor 9% gewijzigd door .oisyn op 01-12-2009 15:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Geef trouwens eens je volledige code. Wat is mmNeighbours bijvoorbeeld voor een type.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
De header file (nog volop in ontwikkeling, niet te hard op letten):

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#pragma once

#include <vector>
#include <tuple>

#include "BasePolygon.h"
#include "XVec3.h"

class WSSVertex;

class SerializedBasePolygon
{
public:

    typedef BasePolygon::VertexID           VertexID;
    typedef BasePolygon::PolygonSignature   PolygonSignature;

    SerializedBasePolygon(const std::vector<XVec3>& vertices, const std::vector<PolygonSignature>& nbs, unsigned int res) : mmVertices(vertices), mmNeighbours(nbs), mmResolution(res)
    {
        if(mmNeighbours.size() != 9){
            throw new std::logic_error("need exactly (not necessarely unique) 9 neighbours for a serialized base poly, aborting construction");
        }
    }
    ~SerializedBasePolygon(){};

    static unsigned int         calculateResolutionSize(unsigned int res);
    static unsigned int         calculateNrVertices(unsigned int triangleSize);

    const std::vector<XVec3>&   getSerialData() const   { return mmVertices;}
    unsigned int                getResolution() const   { return mmResolution;}
    std::vector<XVec3>          getSubsampled(unsigned int downSamples, std::map<PolygonSignature, SerializedBasePolygon*>& nbMap) const;

private:
    std::vector<XVec3>              mmVertices;     // raw data
    std::vector<PolygonSignature>   mmNeighbours;   // 9 neighbours, see documentation for ref
    unsigned int                    mmResolution;   // resolution 0 means 3 vertices, 1 means 6, 2 means 15, ...
    
    std::vector<XVec3>  extractTrace0Border(unsigned int downSamples) const;
    std::vector<XVec3>  extractTrace1Border(unsigned int downSamples) const;
    std::vector<XVec3>  extractBottomBorder(unsigned int downSamples) const;
    const XVec3&        getDownSampledCorner(unsigned int downSamples, const XVec3& corner, const XVec3& notThatOne) const;
    const XVec3&        getBottomLeft() const;
    std::vector<XVec3>  getBorderData(unsigned int downSamples,const XVec3& edgeBegin, const XVec3& edgeEnd) const;
};

Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
Nog een extra test gedaan wegens je opmerking van functie instantiatie, en idd, je hebt gelijk. Wanneer ik een map aanmaak met PolygonSignature als type, de tuple dus, en code laat compileren met operator[], loopt het mis.
Heeft 'key' in std::map een default constructor nodig, of andere operatoren buiten operator< om te kunnen werken?

edit:
Solved, ik heb de typedef tuple<VertexID,VertexID,VertexID> PolygonSignature overboord gegooid en er een volwaardige class van gemaakt. Boeltje compileerd nu.

edit2:
The magic: ;)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
class PolygonSignature
{
public:
    typedef const WSSVertex*                VertexID;
    PolygonSignature(VertexID id0, VertexID id1, VertexID id2) : mmSig(id0, id1, id2)
    {
        
    }
    bool operator<(const PolygonSignature& other) const {return mmSig < other.mmSig; }
private:
    std::tr1::tuple<VertexID,VertexID,VertexID> mmSig;
};

[ Voor 46% gewijzigd door Bob op 01-12-2009 15:51 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

't Blijft raar, ik heb niet echt een fout in je code kunnen ontdekken, en tuple is gewoon default constructable en copy constructable. Het is waarschijnlijk wel een bug in 2010, wellicht wordt ergens intern de verkeerde overload aangeroepen door de nieuwe rvalue reference feature. Gebruik je beta 1 of beta 2?

[ Voor 4% gewijzigd door .oisyn op 01-12-2009 15:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
Beta 2. Kan je iets maken van de error log op pastebin? http://pastebin.com/m5c457aec

Zelfs met de typedefs in de errors blijft het cryptisch voor mij.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik had het daarnet al even door zitten spitten, maar zoals ik al zei, het lijkt erop dat er gewoon ergens intern iets fouts zit ofzo. Als je het echt wilt weten zou ik zeker even de code door de 2008 compiler heengooien en zien of dat wel goed gaat, zo ja dan is het 99.999% zeker een bug in 2010 :).

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
De mop is dat ik daarnet VS 2008 opstartte om de test te doen, en daar niet eens een leeg console project kon compileren ... :D Precompiled header onzin. Morgen meer.

edit: (het is nu morgen)
Net een poging tot testen gedaan, maareuh, VS 2008 heeft natuurlijk nog geen tuple :)

[ Voor 25% gewijzigd door Bob op 02-12-2009 09:25 ]


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
Zou ik hier een bugreport voor aanmaken? Ik kan geen gelijkaardige posts/reports/... vinden:
http://www.google.be/sear...official&client=firefox-a

De code die niet compileert is wel erg simpel, ik vind het dus gek dat ik er niets over terugvind.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdafx.h"

#include <tuple>
#include <map>

int main(int argc, char* argv[]) {
    
    std::map<std::tr1::tuple<int>, int> testmap;
    std::tr1::tuple<int> testKey;
    testmap[testKey];

    return 0;
}

[ Voor 0% gewijzigd door Bob op 02-12-2009 13:32 . Reden: dt foud ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bob schreef op dinsdag 01 december 2009 @ 17:04:
De mop is dat ik daarnet VS 2008 opstartte om de test te doen, en daar niet eens een leeg console project kon compileren ... :D Precompiled header onzin. Morgen meer.

edit: (het is nu morgen)
Net een poging tot testen gedaan, maareuh, VS 2008 heeft natuurlijk nog geen tuple :)
Jawel hoor. Je moet wel even service pack 1 installeren ;)

.edit: dat geisoleerde codevoorbeeld compileert bij mij prima in VS 2008 (met SP1). Het is dus idd een bug :). Je kunt 'm filen bij https://connect.microsoft.com/VisualStudio, maar als jij het niet doet dan doe ik het :P

[ Voor 19% gewijzigd door .oisyn op 02-12-2009 14:02 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 15-09 23:43
Doe gerust, je hebt al een week lang geen bug meer bij hen gefiled ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zal ik vanavond doen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1