Fura hiba Visual C-vel, gcc-vel minden ok.

Fórumok

Tanácstalan vagyok egy fura linkelési hiba miatt.

Van egy szép nagyra hízott projektem ( https://github.com/csikfer/lanview2 ), ami multiplatformos (volt). Ubuntu-n simán lefordul, és működik. Windows alatt Wisual Studio 1017 a fordító, és egy általam értelmezhetetlen hibaüzenettel leáll az lv2g.dll linkelésénél:

lv2.lib(lv2.dll):-1: error: LNK2005: "public: int __cdecl QList<class QString>::size(void)const " (?size@?$QList@VQString@@@@QEBAHXZ) already defined in input_dialog.obj
lv2.lib(lv2.dll):-1: error: LNK2005: "public: class QString const & __cdecl QList<class QString>::operator[](int)const " (??A?$QList@VQString@@@@QEBAAEBVQString@@H@Z) already defined in input_dialog.obj

Az input_dialog.cpp -ben a következő metódus okozhatja a hibát:

void cSelectDialog::setValues(const QStringList& values, bool _m)
{
    QAbstractButton *pButton;
    int id, n = values.size();
    for (id = 0; id < n; ++id) {
        const QString& val = values[id];
        if (_m) pButton = new QCheckBox(val);
        else    pButton = new QRadioButton(val);
        pButtonGroup->addButton(pButton, id);
        pLayout->addWidget(pButton);
    }
    pLayout->addWidget(pDialogButtons);
    pButtonGroup->setExclusive(!_m);
}
A QStringList két inline metódusának hívásánál keletkezik a hiba, legalábbis, ha ezeket kiveszem, akkor lefordul.

Ha ez fordítói hiba, akkor nagyon furmányos, mert nincs rá találat a Google-n, és abban a pár ezer sorban hasonló módon jó párszor használt QStringList objektum esetén minden ok.

Ha én hibáztam, akkor is furmányosra sikeredett, mert gcc simán lefordítja, és egy elég egyszerű algoritmus, amit elhibázni sem könnyű.

Áthidaló megoldás sem igen jut eszembe (ill. amit próbáltam, az nem segít).

Hozzászólások

clean solution + rebuild solution?

~ubuntu, raspbian, os x~

Nem vagyok nagy Windows tudor. A Visual Studio-t sem használom közvetlenül, a fenti parancsokat meg fogalmam sincs hogyan kéne kiadni QtCreator alól.

Amúgy többször próbáltam nulláról újra fordítani, de nem jött be. De most megpróbálom az itthoni gépemen, még nullábbról, hátha.

Szerkesztve: 2019. 12. 14., szo – 16:58

Régi kódolási stílust használsz, valószínűleg ez egy szimbólum import/export hiba a Qt-ben. Próbáld meg iterátoros ciklussal vagy for range megoldással:

void cSelectDialog::setValues(const QStringList& values, bool _m)
{
    QAbstractButton *pButton;
    int id = 0;
    for (auto& val: values) {
        if (_m) pButton = new QCheckBox(val);
        else    pButton = new QRadioButton(val);
        pButtonGroup->addButton(pButton, id++);
        pLayout->addWidget(pButton);
    }
    pLayout->addWidget(pDialogButtons);
    pButtonGroup->setExclusive(!_m);
}

Ettől nem lett jobb. Így a begin() és end() metódusokra mondja, hogy redefined. Előszór a foreach makrót használtam, az lényegében ugyan ez, ugyan ezzel a hiba üzenettel, aztán átírtam párszor: QStringList::iterator -ral, és QListIterator<QString> -el, de nem jött be. Valószínűleg máshol van a turpisság.

A régi kódolási stílus nem véletlen, én még régebbi vagyok, kb. 35 éve írtam első C programomat. Lassan erre a projekre is rá lehet mondani, hogy régi.

Nem kritika akart lenni, hanem egy lehetséges ok, ami a hibát okozza (néha a régi dolgokat nem mindig frissítik megfelelően). Ebben az esetben a két stílus más-más metódust hív meg. Ha a másik sem jó, akkor az input_dialog.obj nem kapja meg a Q_DECL_EXPORT-ot fordításkor, ez okozza a szimbólum hibát. A GCC a -fvisibility=hidden megadásakor ugyanúgy fog viselkedni, mint az MSVC.

https://gcc.gnu.org/wiki/Visibility

https://doc.qt.io/qt-5/sharedlibrary.html

Nem vettem kritikának, ill. nem találtam sértőnek. Sajnos, amíg az öregedés egyetlen ellenszere a korai halál, addig inkább elfogadom az öregedést, a mellékhatásokkal együtt.

Nekem is az a gyanúm, hogy az export/import környékén lehet a kavarás (ami a gcc-nél alapesetben nem létezik), de ha kinézem a szemem sem jövök rá hogy hol a hiba. Hazafelé az volt a nagy ötlet, hogy ez ügyben kevertem el egy makrót, de nem, vagy csak nem látom.

Hát, még MSVC bug is lehet, pár perc alatt ezt találtam:

https://forum.qt.io/topic/24521/problem-building-qt-5-0-1-visual-studio…

"For individuals: Any individual developer can use Visual Studio Community to create their own free or paid apps." Tényleg érdemes lenne frissíteni.

https://visualstudio.microsoft.com/vs/community/

Az 5.13.2 -vel fordítottam eddig debug módban (csak mert az a default), letöltöttem a Qt 5.12.6 és a 5.14.0 -t. Az 5.12.6 -nál ugyan az, a 5.14.0 -val millió hiba egy a QtCore-ban lévő header-re. Aztán próba-cseresznye alapon átállítottam release módra, és lőn csoda lefordul az 5.12.6 és 5.13.2 -vel is, az 5.14.0 az úgy tűnik bugos. Érteni nem értem, de ezzel túl tudok lendülni a problémán, debug-olni windows alatt eddig sem tudtam, Linux alatt lehet, nem küzdöttem vele.

Azért a Qt, QtCreator, Visual C 2017 kombóban van más probléma is, nagy ívben leszarja az alprojektek függőségét. Képtelen vagyok lebeszélni a QtCreatort a bődületes mennyiségű warning-ról (eddig a NULL-t pampogta meg, most itt a Windows alatt meg a nullptr-t, meg mindent ami nem C++98 kompatibilis)

Nem nevezném megoldásnak, de így már megkerülhető a dolog.

a QtCreatort a bődületes mennyiségű warning-ról (eddig a NULL-t pampogta meg, most itt a Windows alatt meg a nullptr-t, meg mindent ami nem C++98 kompatibilis)

Az a clang code model warningjai: nem fordítás időben keletkeznek hanem menetközben parsolja a fájlokat. Itt tudod kikapcsolni:

https://i.imgur.com/UXjKaNw.png

OK, értem én hogy ki lehet kapcsolni. Eddig az volt a fixa-ideám, hogy minden warning bekapcsolva, és addig küzdünk, míg egy warning sincs.

Mikor a QtCreator és a gcc szigorodott pár éve, akkor több programhibámat is lebuktatta, jelenleg elvesznek az értelmes üzenetek a értelmetlenek között. Sőt, kapok olyan üzeneteket is ami totál hülyeség, pl.: noreturn metódus a végén meghívok egy noreturn metódust, erre közli, hogy a noreturn függvényem nem noreturn. A VC millió hibaüzenetet ad a try blokkban, hogy nem inicializálok egy változót, pedig de. Nincs olyan nullpointer amit valamilyen szempontból ne ugatna le.

OK. Nem triviális beállítani, de kis utánaolvasással nem gond.

Azért engem zavar, hogy minden QtCreator példány máshogy viselkedik:

Az otthoni Ubuntu-n be van állítva a -W-no-c++98-compat (biz isten nem én voltam, más meg nem lehetett) és ennek megfelelően működik. A munkahelyi gépemen ugyan ez az ubuntu verzió, nem ugyanakkor installált QtCreator: nincs beállítva ez a kapcsoló, de ennek ellenére ez sem reklamál. A két windows gépen, amit próbáltam, mindkettőn be kellet állítani ezt az opciót.

Még azt lenne jó kitalálni, hogy mit kell mondani a Windows-os változatnak, hogy méltóztasson figyelembe venni az alprojektek függőségét?

Próbáltál már rákeresni a "Wisual Studio 1017" ismert hibáira? Lehet, hogy ebben az I. (Nagy) Knut idejéből származó verzióban van valami azóta már javított bug. Bocs :-)