2020-12-31T14:48:00+01:00
2021-06-23T15:33:25+02:00
2022-07-19T01:43:06+02:00
x00
Tisztelt tagság!
Visual C++ 2019 Community 16.8.3
64 bites Windows 10 Home 2004 teljesen befrissítve
Van egy sokat tudó AVL-fákat használó programom, mely 32 biten mindenhogy megy. 64 biten debug módban megy, release módban a -1-es címről (0xFFFF...) akar olvasni az AVL-fa rutin, 0xCCCC... címeket is látok ami definiálatlant jelent. Ha * helyett * __ptr32 van, akkor 32 bitesek a címek, ekkor debug módban se megy, még hamarabb jelentkezik a hiba, ekkor is -1-es címről akar olvasni. A fordítóprogramban lenne a hiba? Találtam már egyébként pár hibát a fordítóprogramban. Mivel hosszú, még nem készítettem el a legrövidebb, legegyszerűbb változatot amiben jelentkezik a hiba, pár 10 000 soros a forráskód. Egyébként natív unmanaged parancssoros program, a projekt fájl közel 20 éves, többször átkonvertálta, így nincs benne még MASM se, új projekt fájlt kellett létrehoznom hogy be tudjam állítani hogy a routine.asm MASM-mal fordul, nem marad ki. Azokat az AVL-rutinok nem használják.
Na úgy néz ki nemsokára lesz egy rövid program amiben jelentkezik a hiba. int-eket tartalmazó AVL-fába 0-t betettem, utána a -1-et már nem tudta betenni, 0xFFF....FFF3-as címről akar olvasni. Én továbbra is a fordítóprogramra gyanakszok. Ennél 32 bites címeket használok 64 bites programnál. Nyilván a linkelésnél beállítottam hogy csak az alsó 2 GB-ot használja. Bonyolultabbnál 64 bites címeknél is jelentkezik a hiba, de csak release módban. Ez a fura, hogy 32 bites programnál mindig megy, ezért gyanakszok fordítóprogram-hibára.
Visual C++ 2019 Community 16.8.3
64 bites Windows 10 Home 2004 teljesen befrissítve
Van egy sokat tudó AVL-fákat használó programom, mely 32 biten mindenhogy megy. 64 biten debug módban megy, release módban a -1-es címről (0xFFFF...) akar olvasni az AVL-fa rutin, 0xCCCC... címeket is látok ami definiálatlant jelent. Ha * helyett * __ptr32 van, akkor 32 bitesek a címek, ekkor debug módban se megy, még hamarabb jelentkezik a hiba, ekkor is -1-es címről akar olvasni. A fordítóprogramban lenne a hiba? Találtam már egyébként pár hibát a fordítóprogramban. Mivel hosszú, még nem készítettem el a legrövidebb, legegyszerűbb változatot amiben jelentkezik a hiba, pár 10 000 soros a forráskód. Egyébként natív unmanaged parancssoros program, a projekt fájl közel 20 éves, többször átkonvertálta, így nincs benne még MASM se, új projekt fájlt kellett létrehoznom hogy be tudjam állítani hogy a routine.asm MASM-mal fordul, nem marad ki. Azokat az AVL-rutinok nem használják.
Na úgy néz ki nemsokára lesz egy rövid program amiben jelentkezik a hiba. int-eket tartalmazó AVL-fába 0-t betettem, utána a -1-et már nem tudta betenni, 0xFFF....FFF3-as címről akar olvasni. Én továbbra is a fordítóprogramra gyanakszok. Ennél 32 bites címeket használok 64 bites programnál. Nyilván a linkelésnél beállítottam hogy csak az alsó 2 GB-ot használja. Bonyolultabbnál 64 bites címeknél is jelentkezik a hiba, de csak release módban. Ez a fura, hogy 32 bites programnál mindig megy, ezért gyanakszok fordítóprogram-hibára.
Mutasd a teljes hozzászólást!
Az lehet egyébként, hogy a __ptr32 és az & (address of) operátor nem úgy működnek együtt, mint ahogyan azt gondolnád: https://developercommunity.visualstudio.com/content/problem/620885/-..
Mutasd a teljes hozzászólást!
- hoszaválasza x00 (14:48) részére
- 2020.12.31. 16:40
- permalink
Forráskód híján elég nehéz megtippelni, mi lehet a hiba forrása. Mi lehet a különbség 64 és 32 bites mód között? Ekörül keresgélj: sizeof, size_t, ponter méretek, int_max, alignment és padding stb. Ha fordítóprogram hibára gyanakszol, akkor igazolhatod vagy cáfolatod a sejtésedet, ha másik fordítót is kipróbálsz. Ennek a legkisebb az esélye amúgy, de a te idődről van szó...Mutasd a teljes hozzászólást!- x00válasza hosza (16:40) részére
- 2020.12.31. 17:17
- permalink
64 bites mutatóknál is előjön a hiba, azt még nem tudom mi okozza.
32 bites mutatóknál viszont a fordítóprogram a hibás. A **p már problémát okoz neki ha * __ptr32 * vagy * __ptr32 * __ptr32. p jó, *p is jó, **p az AVL-elem amit hasonlítani kell: *p a címe. Mire meghívja az operator <-et, már -D a cím: 0xFFFF...FFF3. Közvetlenül előtte kiírattam wcout-ra mindent: this, p, *p, előtte a gyökeret és a 2 részfa címét. Ez jó, és leáll, hogy erről a címről olvasott. Van call stack, autos, stb. A beszúró rutin keresi a helyét. Üres fába 0-t beszúr, utána bármit is szúrok be, mire meghívja az operator <-et a keresés, már megváltozik a gyökérelem címe: például *p
= E7FF10, de az operator < már 0xFFF...FF3-at kap **p aktuális paraméterre, const AVL-elem &y formális paraméterre. Az autos méghibásabb, ott hiába 32 biten tároltam a címeket, ad hozzá felső 32 bitet is, de nem 0-t hanem 1, CCCCCCCC, stb. A CCCCCCCC a definiálatlan: gondolom az autos 64 bitet olvas ki a memóriából.
Most kezdem azt a hibát keresni ami 64 bites mutatóknál is előjön.
Másik fordítóm nincs, és tudtommal a * __ptr32-t csak a Visual C++ tudja, az is csak papíron mint kiderült.
A másik is fordítóprogram hiba volt. Szép, hogy a Visual C++ nem képes AMD64-re fordítani. A beszúrásnál a gyökértől indulva keresi a helyét. Minden lépés előtt kiírattam p, *p, into-t. *into vagy **p már -1-es cím: into vagy *p = 1 a p = részben:
telem **p = &root; while (*p) { it.put(*p); std::wcout << p << L' ' << *p << L' ' << into << std::endl; p = (*p)->avld.p + ! (*into < **p); }
Lehet hogy a project beállításai között valamit eltoltam? Nem állítgattam különösebbeket: LARGE_ADDRESS_AWARE ki, Unicode, fp:precise, #include esetén hol keresse a saját rutingyűjteményemet, induló aktuális könyvtár, stb.Mutasd a teljes hozzászólást!- Csaboka2válasza x00 (17:17) részére
- 2020.12.31. 17:47
- permalink
Tényleg kéne valami kód, mert így csak tippelgetni lehet. Minden esetre ez alapján:
Üres fába 0-t beszúr, utána bármit is szúrok be, mire meghívja az operator <-et a keresés, már megváltozik a gyökérelem címe
nekem gyanús, hogy az operator< lesz a hunyó. Valahogy a hívó nem azt pakolja a veremre mint amit a hívott vár, és onnantól már simán lehet hogy felülfirkálja a hívó lokális változóit.
De persze ez is csak egy tipp.Mutasd a teljes hozzászólást!- x00válasza Csaboka2 (17:47) részére
- 2020.12.31. 17:57
- permalink
// AVL-elem template: only search key template<typename t, template<typename> class selem> class teavl: public selem<teavl<t, selem> > { public: friend void swap<>(teavl &, teavl &); template<typename tt> friend void swap(tt &, tt &); typedef t tkey; typedef t telem; tkey key; explicit teavl(const tkey &x): key(x) {} explicit teavl(tkey &&x): key((tkey &&) x) {} template<typename t> bool operator == (const t &other) const { return key == other; } template<typename t> bool operator != (const t &other) const { return key != other; } template<typename t> bool operator <= (const t &other) const { return key <= other; } template<typename t> bool operator >= (const t &other) const { return key >= other; } template<typename t> bool operator < (const t &other) const { return key < other; } template<typename t> bool operator > (const t &other) const { return key > other; } }; template<typename t, template<class> class s> bool operator == (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key == y.key; } template<typename t, template<class> class s> bool operator != (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key != y.key; } template<typename t, template<class> class s> bool operator <= (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key <= y.key; } template<typename t, template<class> class s> bool operator >= (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key >= y.key; } template<typename t, template<class> class s> bool operator < (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key < y.key; } template<typename t, template<class> class s> bool operator > (const teavl<t, s> &x, const teavl<t, s> &y) { return x.key > y.key; }
Amikor a mutatók is 64 bitesek voltak: ekkor nem volt * helyett * __ptr32, akkor el se jutott az operator <-ig, hanem egyszerűen a p = sorban a beszúrásnál -1-es címről olvasott, holott közvetlenül előtte a wcout <<-ban még nem volt -1-es cím.Mutasd a teljes hozzászólást!- x00válasza x00 (17:57) részére
- 2020.12.31. 18:20
- permalink
class elem { public: elem * __ptr32 (p[2]); int key; }; bool operator < (const elem &x, const elem &y) { return x.key < y.key; } elem * __ptr32 root = nullptr; void insert(elem *i) { i->p[1] = i->p[0] = nullptr; elem * __ptr32 * __ptr32 p = &root; while (*p) p = (*p)->p + ! (*i < **p); *p = i; } int wmain() { insert(new elem); insert(new elem); return 0; }
Mutasd a teljes hozzászólást!- x00válasza x00 (18:20) részére
- 2020.12.31. 20:50
- permalink
Azt sajnos nem tudom hogy lehetne visszatérni a Visual Studio korábbi változatához, úgyhogy megvárom a 16.8.4-et, aztán annál majd újra próbálkozok, hátha sikerül. Egyébként a számítógépet újraindítva is ugyanaz mindig. Több bites memóriahiba javítását is tudja a számítógépem, be is van kapcsolva. Próbáltam a Visual Studio-t újratelepíteni is: repair.Mutasd a teljes hozzászólást!- NevemTeveválasza x00 (14:48) részére
- 2020.12.31. 21:25
- permalink
Ha kiszeded az összes __ptr32 -t, akkor jó lesz?Mutasd a teljes hozzászólást!- hoszaválasza x00 (18:20) részére
- 2020.12.31. 21:47
- permalink
A példakód a legegyszerűbb program lett volna amiben előjön, de ebben nem jött elő a hiba.
Tehát továbbra is csak ott tartunk, higy a 10000 sorban van valahol egy vagy több h8ba. Az irány jó azonban, le kell szűkíteni a kört, ahol keresni kell.Mutasd a teljes hozzászólást!- x00válasza NevemTeve (21:25) részére
- 2020.12.31. 21:52
- permalink
Nem lesz jó. De egyébként már írtam: az összes __ptr32 kiszedése az az amikor 64 bites módban 64 bites mutatók vannak. Erről írtam, hogy ennél is jelentkezik a hiba, ekkor van hogy az operator <-et meg se hívja. A programban * helyett pdef van, és van egy
#define pdef * __ptr32
az elején, ebből csináltam * // __ptr32-t. A kód maga ugyanaz mint a rövid program, de abban nem jelentkezik a hiba: ha sablonba teszem, stb. akkor persze hibás, hiszen nálam is hibás, és pont az a kód van benne. Az eredeti program részletei a korábbi hozzászólásaimban vannak. Röviden: a program hibával leáll, a debugger a p = -s sornál írja ki hogy a 0xFFFF... címről próbált olvasni, call stack-kel se lehet lejjebb menni a veremben: ez van legalul. Előtte meg wcout << p, *p, into volt, és akkor még jó volt. Ez bizony a fordítóprogram hibája már megint.Mutasd a teljes hozzászólást!- x00válasza hosza (21:47) részére
- 2020.12.31. 21:55
- permalink
Az előző hozzászólásom végéből is az derül ki, hogy nem nálam van a hiba. Az a rövid program ugyanaz a kód. Ha a fordítóprogram jó, akkor neki mindegy, hogy a key mező típusa int, vagy sablonparaméter, melynek az aktuális értéke épp most int: mivel ez pont ugyanazt jelenti! Több 10 000 sor egyébként, és ha az AVL-fában 1 elem van, a következőt már nem tudja beszúrni: egyes típusoknál jelentkezik, másoknál meg nem. Ott a kód az eredetiből is, úgy ahogy van, sablonosan. Azért az árulkodó hogy a használat előtt közvetlenül még nem -1 a cím: ott a wcout << p, *p, into közvetlenül előtte, írtam az eredményét is. Azt se hagyjuk már ki, hogy ugyanaz a program 32 bitesen simán megy, release és debug módban is. sizeof, stb. meg nincs benne, int és cím közötti konvertálás se.Mutasd a teljes hozzászólást!- hoszaválasza x00 (18:20) részére
- 2020.12.31. 22:28
- permalink
A root az nullptrt tart kezdetben.
Aztán p-ben eltárolod root címét.
p = (*p)->p + ! (*i < **p);
(*p)->p értéke mi lesz ekkor szerinted?
Ja, hogy bele sem megy a ciklusba. :)Mutasd a teljes hozzászólást!- NevemTeveválasza x00 (21:52) részére
- 2021.01.01. 06:01
- permalink
Szerintem csinálj egy mvce-t (How to create a Minimal, Reproducible Example - Help Center) de ne legyen benne se __ptr32, se template.Mutasd a teljes hozzászólást!- x00válasza NevemTeve (06:01) részére
- 2021.01.01. 09:42
- permalink
Az megvan, nem jelentkezik benne a hiba: ki kell törölni belőle a __ptr32-ket. A fordító rossz, valami zavarja: template, stb. Vagyis például ha c<int> helyett csinálok egy cint osztályt, már jól működik. Valami ilyesmi hibája lehet. Elég egyértelmű, hogy **p előtt kiíratom a képernyőre p, *p-t, 1-32 MB közötti cím, majd a debugger azt írja hogy a -D ... -1 közötti címről próbált olvasni. Ez csak a fordítóprogram hibája lehet. Megvárom a következő javító kiadást, addig maradok 32 biten.Mutasd a teljes hozzászólást!- aPar aLyzaválasza x00 (14:48) részére
- 2021.01.01. 10:00
- permalink
Te vagy a hunyó!
Első kérdés: sizeof(int) 4 vagy 8?
Tippem:
A probléma a -1 esetében, hogy a 64 bites stack érték (pointer) felső része kerül egy 32 bites int változóba.Mutasd a teljes hozzászólást!- x00válasza aPar aLyza (10:00) részére
- 2021.01.01. 10:32
- permalink
Nem, a fordítóprogram. Az int 4 byte-os. A -1-et már nem írja ki a program, azt már a debugger írja ki. Leegyszerűsítve:
cout << p << ' ' << *p << endl;
**p;
2 darab 1-32 MB közötti, 64 bites címet ír ki: 16 számjegy.
Utána a következő sor hibával leáll, és azt mondja hogy a 0xFFFFFFFFFFFFFFFy címről próbált olvasni, de az a memóriaterület nem érhető el, így nem sikerült neki. y többféle lehet, 3 is szokott lenni. Ez csak a fordítóprogram hibája lehet.Mutasd a teljes hozzászólást!- x00válasza x00 (10:32) részére
- 2021.01.01. 10:55
- permalink
Na közben rájöttem hogy más a hiba. Szóval azt észrevettem, hogy a watch, autos, locals a változókban tárolt címeknek tök hülyeségeket ír ki, úgy rossz ahogy van. Ugyanígy, az is hibás, hogy azt írja ki hogy a -D - -1 közötti címről olvasott: elérhetetlen memóriaterületről olvasott, de nem arról a címről amit kiír, hanem arról amit a képernyőre írt ki a wcout <<. Vagyis a cím nem -1, -D, stb. csak a debugger hibás, és azt állítja. A root tartalmazza az AVL-fa gyökérelemének címét. Ez mutat olyan területre ami nem olvasható. Csak 64 bit release módban, és csak egyes elemtípusoknál: más típusnál egész nagy fáknál is ment, még mielőtt kiakadt volna. Na akkor megnézem hol akad el, előtte kiíratom a gyökeret, tartalmát. Megnézem, hogy 1 elem beszúrása után gyökér a beszúrt elem címe-e, mezői olvashatók-e. De szerintem az lesz, vagyis nem csak a debugger, hanem a fordító is hibás lesz.
Igen, tényleg a fordítóprogram hibás. Beszúrás előtt kiírattam a gyökér és a beszúrandó elem címét a képernyőre. Valóban üres fánál 0 gyökér. Utána a gyökérelem 2 mutatóját: 0 valóban, tehát ez a terület igenis olvasható. A rendezési kulcsot is kiírta, tehát az is olvasható. A következő elem beszúrása előtt is kiírattam a gyökér és beszúrandó elem címét. A gyökér az előzőleg beszúrt elem. Itt már a beszúrás előtt írattam ki a beszúrandó elem 2 mutatóját és a keresési kulcsot, mivel a beszúrás utáni kiírások már nem futnak le, mert kiakad előttük a program. Tényleg 0, és kiírta, tehát ez a memóriaterület olvasható. A ciklusban a részfára lépés előtt most is kiírattam: p, *p, into, vagyis a gyökér címét tartalmazó változó címét, a gyökér címét, és a beszúrandó elem címét. Ezek is jók: pont az aminek lennie kell: az előzőleg beszúrt és a most beszúrandó elem címe. És itt már nem tudta olvasni azt a memóriaterületet amit a beszúrási rutin meghívása előtt még tudott olvasni.Mutasd a teljes hozzászólást!- chiefaválasza x00 (10:55) részére
- 2021.01.01. 12:43
- permalink
Annak a kódnak, amely 32 bites változatban lefordul és hibátlanul fut, a 64 bites változatban is hibátlanul fordulni és futnia kell?
Ha tippelnem kéne, akkor a két környezetben az eltérő pointer méretek miatti memória felülírás okozza a gondot.
a beszúrás utáni kiírások már nem futnak le
Akkor érdemes lenne bele debuggolnod a generált kódba, és megnézned, hogy a beszúráskor a mutató írása jó címre és mérettel történik-e?
a pointerek használata
ami közvetlenül érinthet az a 3. bekezdésMutasd a teljes hozzászólást!- x00válasza chiefa (12:43) részére
- 2021.01.01. 13:22
- permalink
Jelenleg nincsenek keverve a típusok: 64 bitesre fordításnál 64 bites a mutató: * van csak, nincs __ptr32. És természetesen semmilyen típuskonverzió sincs: se egészre, se másra, egészből másra se! A mezőtípus, lokális változók típusa, stb. egyszerűen *, nem int! Mivel közvetlenül a hiba előtt kiírattam a képernyőre, csak a fordítóprogram hibája lehet: lefut a kiírás, majd kiakad a program.Mutasd a teljes hozzászólást!- hoszaválasza x00 (13:22) részére
- 2021.01.01. 14:03
- permalink
warning C4244: 'initializing': conversion from 'elem * __ptr32*' to 'elem * __ptr32* __ptr32', possible loss of data warning C4244: '=': conversion from 'elem *' to 'elem * __ptr32', possible loss of data11 warning C4244: '=': conversion from 'elem * __ptr32*' to 'elem * __ptr32* __ptr32', possible loss of data
Tudnál egy olyan változatot küldeni, ahol nincs warning sem és templatek is vannak (mert szerinted ott romlik el valami), és ahol tényleg olvasási hibát kapunk futtatáskor?
Mert az a kód, amit küldtél, az a while(*p) sorban meghal, még bele sem megy a ciklus törzsébe, nem hogy wcouttal bármit is kiiratna.Mutasd a teljes hozzászólást!- hoszaválasza x00 (13:22) részére
- 2021.01.01. 14:17
- permalink
Jelenleg nincsenek keverve a típusok: 64 bitesre fordításnál 64 bites a mutató: * van csak, nincs __ptr32. És természetesen semmilyen típuskonverzió sincs
Dehogy is nincsenek, pont azért kapod a warningokat, amit beidéztem...Mutasd a teljes hozzászólást!- Az lehet egyébként, hogy a __ptr32 és az & (address of) operátor nem úgy működnek együtt, mint ahogyan azt gondolnád: https://developercommunity.visualstudio.com/content/problem/620885/-..Mutasd a teljes hozzászólást!
- x00válasza hosza (14:29) részére
- 2021.01.01. 14:40
- permalink
Írtam, hogy ha nincs template, stb. akkor nem jelentkezik a hiba! Amiben jelentkezik, abban nincs __ptr32, és csak 1 típusnál jelentkezik a hiba! Írtam azt is hogy beállítottam linkelésnél hogy csak az alsó 2 GB-ot használja. Azt is írtam hogy a képernyőre kiírt címek 1-32 MB közöttiek. Több 10 000 sor sablonnal együtt, le lehetne rövidíteni hogy csak a használtakat, de minek? Úgyis több 100 sor, és úgyis a fordítóprogram hibája, felesleges vele foglalkozni.Mutasd a teljes hozzászólást!- hoszaválasza hosza (14:17) részére
- 2021.01.01. 14:43
- permalink
Egyébként mi a szándékod ezzel az egész 32 bites pointer trükközéssel? 64 bites módban a mutatók kétszer annyi memóriát foglalnak el, ezzel akarsz spórolni?
Az nem gond, hogy a "new elem" hivások 64 bites memória címeket adnak vissza és ha ezeket bármikor átalakítod 32 bitesre, akkor elveszted a felső biteket? Nekem a példa kódodban az első elem már a 0x000001ffc53b19a0 címen kerül lefoglalásra és ez sehogy sem fér el 32 biten.
Ha tényleg memóriával akasz spórolni, akkor célszerűbb pointerek helyett indexeket használni és nem new-t hanem saját memória poolt használni az elem típushoz.Mutasd a teljes hozzászólást!- x00válasza hosza (14:43) részére
- 2021.01.01. 14:46
- permalink
Spórolás lenne, mert tiszta AVL-fa az egész.
Mert az a kód, amit küldtél, az a while(*p) sorban meghal, még bele sem megy a ciklus törzsébe, nem hogy wcouttal bármit is kiiratna.
Szedd ki a __ptr32-t, vagy a linkernél kapcsold ki a LARGE_ADDRESS_AWARE-t. És nem ez írja ki, hanem a nagy eredeti program a címeket. Na mingyár összeszedem neked amit használok belőle. És a new nekem az alsó 2 GB-ba adja!Mutasd a teljes hozzászólást!- NevemTeveválasza x00 (14:46) részére
- 2021.01.01. 15:28
- permalink
Esetleg lehetne olyan, hogy egy darab, önmagában fordítható, tesztelhető source, amit mutatja a problémát, de nincs benne semmi, ami nem esszenciális a hiba bemutatásához?Mutasd a teljes hozzászólást!- hoszaválasza x00 (14:46) részére
- 2021.01.01. 15:35
- permalink
A __ptr32 továbbra is problémás, lásd a mellékelt screenshotot. Annyival bővítettem a példádat, hogy az elemhez létrehoztam egy konstruktort, ami kitölti a key-t és a ptr értékeket. Így a mainban van egy insert(new elem(1)) és 2-vel ugyanez.
Ez előhozta az egyik hibádat, ti. az operator< referenciákat a fordító mutatókra fordítja, de a jelek szerint fixen 64 bites címet vár a referencia esetén és nem 32 bitest, így a key=1 érték "hozzácsapódik" az elem címéhez. (Itt már kikapcsoltam a large addresseket és nálam is 2G alatt generált a new új címeket) tehát az 100c50fb0 címről akar olvasni azért mert key=00000001 volt.Mutasd a teljes hozzászólást!Csatolt állomány- bug.png38,54 KB
- hoszaválasza hosza (15:35) részére
- 2021.01.01. 15:46
- permalink
És igen, tényleg úgy néz ki, a debugger nem támogatja a 32 bites pointereket, mert a root-ot megvizsgálva tényleg rosszul mutatja az értékeket, de ha írok egy sima rekurzív print rutint a fához, akkor az jól kíírja a beszúrt 1 és 2 értékeket.
Persze ez még továbbra sem jelenti azt, hogy fordító hibát találtál.Mutasd a teljes hozzászólást!- x00válasza hosza (15:46) részére
- 2021.01.01. 17:21
- permalink
Persze ez még továbbra sem jelenti azt, hogy fordító hibát találtál.
Dehogynem!
int a;
int * __ptr32 p = &a;
int b = 1;
void f(const int &x) { x; }
f(*i)
Ebben az egyszerű példában itt a vermen van, így nem jön elő, de struct-ban, tömbben előjöhet.
Amennyiben a cím felső 32 bitje f hívásánál nem 0, hanem 1, a b miatt, akkor az hiba! Egyszerűen hibás a *i kifejezés, ha referenciának adjuk át, és i típusa * __ptr32. Ez bizony a fordítóprogram hibája!
Az is hiba, hogy ha MASM-mal fordított, külön fordítási egységben levő, extern "C"-vel deklarált rutinban van a hiba, akkor utána még több hívási szintet ugrik, mire a call stack megtalálja. Na jó, ez a release módban levő optimalizáció miatt van, de felfoghatatlan így is, hogy akkor debug módban ugyanaz a rutin miért jó? Ennél nem volt __ptr32, tehát 64 bitesek voltak a mutatók, és érdekes módon debug módban nem jelentkezett a hiba. Szóval a keresési kulcs unicode szöveg volt, és érdekes módon release módban valahogy rossz címről olvasott, debug módban meg jó címről, ugyanaz az általam írt assembly rutin! 64 biten tárolt mutatóknál! Na mindegy, most C++ ciklussal hasonlítom össze a 2 szöveget, így már 64 bites mutatóknál jó, de 32 biteseknél előjön a hiba amit írtál. Köszi a segítséget amúgy.
Amit linkeltél hibabejelentést, ott azt írták hogy folyamatban van a javítása, szóval remélem hamar kijön a 16.8.4 és annál már jó lesz. A másik hiba tényleg nálam volt, biztos más a cím debug és release módban. Köszönöm a segítséget! Mivel a teljes adatszerkezet szinte tisztán mutató: AVL-fa, és a tárolt hasznos adat is sokszor mutató, megvárom a hibajavítást. 64 biten szinte minden méret a duplájára nőne, így belassulna, bár lehet, hogy a 7 regiszter helyett 15 behozná (RSP nélkül).Mutasd a teljes hozzászólást!- NevemTeveválasza x00 (17:21) részére
- 2021.01.01. 18:03
- permalink
Namostan az ok, hogy nincs meg a forráskód gomb, de az 'i' változó az ugye 'p' akart lenni?
És miért a fordító hibája az, hogy te szándékosan rossz kódot alkotsz? Pontosabban mondva, a te felelősséged, hogy csak olyan adatokat címezz ezzel a pointerrel, amik a 64-bites címtartomány legalján (vagy legtetején(*)) helyezkednek el.
A másik problémád oka inicializálatlan változó lehetett, de ezt mindenképpen külön topikban kellene tárgyalni.
(*) attól függ, hogy a felső 32 bitet fixen nullára veszi-e, vagy előjelkiterjesztés végez (én az utóbbira tippelek)
Szerk: lehet, hogy a te panaszod éppen az, hogy felfedezted, hogy a 32-bites cím 'kiterjesztés' az előjelesen történik? Mert akkor a jó hír az, hogy ez nem hiba.Mutasd a teljes hozzászólást!Csatolt állomány- source.jpg9,5 KB