Integer promotions in C++ - странен warning.
11 отговора
783 прегледа
Integer promotions in C++ - странен warning.
Кода е следния:
short s1, s2;
s1 += s2;
Какво се случва тук - компилатора на MS VS.NET 2003 (VC 7.1) дава:
warning C4244: '+=' : conversion from 'int' to 'short', possible loss of data
s1 = s1 + s2;
Горното минава без warning (оставаше и тука да има, тогава щеше да има искрено МУАХАХАХАХ).
Моето обяснение за причината за warning-a: поради това, че с целочислените типове се прави имплицитен integral promotion, междинния резултат (s1+s2) се слага в int32 регистър, и след това се присвоява на s1, и това води до warning-a.
Обяснението за липсата на warning при втория statement: резултата от (s1+s2) се слага директно в регистъра за s1 (int16), но е налице оптимизация - разпознаване, че s1 и s2 са от един тип, и техния резултат е от същия тип както left-hand-side-а.
Нещо да добавите и/или да поправите в разсъжденията ми?
short s1, s2;
s1 += s2;
Какво се случва тук - компилатора на MS VS.NET 2003 (VC 7.1) дава:
warning C4244: '+=' : conversion from 'int' to 'short', possible loss of data
s1 = s1 + s2;
Горното минава без warning (оставаше и тука да има, тогава щеше да има искрено МУАХАХАХАХ).
Моето обяснение за причината за warning-a: поради това, че с целочислените типове се прави имплицитен integral promotion, междинния резултат (s1+s2) се слага в int32 регистър, и след това се присвоява на s1, и това води до warning-a.
Обяснението за липсата на warning при втория statement: резултата от (s1+s2) се слага директно в регистъра за s1 (int16), но е налице оптимизация - разпознаване, че s1 и s2 са от един тип, и техния резултат е от същия тип както left-hand-side-а.
Нещо да добавите и/или да поправите в разсъжденията ми?
Re: Integer promotions in C++ - странен warning.
Сефте ми се случва да похваля Джавата, ама там тоя проблем са го решили доста елегантно... 
Re: Integer promotions in C++ - странен warning.
ми предифинирай си += и да не ти пука.
Re: Integer promotions in C++ - странен warning.
Не виждам защо да не може и при s1+=s2 да не разбере, че са от 1 и същи тип и да не даде warning, т.е. логиката ти нещо куца :)
Машина за отделяне на кожа и сланина от парени свине
Машина за отделяне на кожа и сланина от парени свине
Re: Integer promotions in C++ - странен warning.
Мога само да предполагам... то неведоми са пътищата на писачите на компилатори, ама:
По подразбиране (поне за мен) операциите от тип += или изобщо някаква_си_Аритм/Лог.операция=, са били първоначално замислени като регистрови такива. Всъщност реално оптимизация от гледна точка на код и бързодействие (при липса на фп копроцесор, пък и при наличието му май все тая) имаме само когато и двата операнда са не по-големи от регистъра на АЛУ-то който се ползва. И то за цели числа. И то ако инструкциите на процесора позволяват подобно нещо.
Примерно да кажем за едно ядро, което позволява резултата от операцията да не остане в акумулатора ( А/Лрегистър на процесора), ами да се запише директно в паметта, или когато са допустими операции регистър/регистър или памет/памет.
За а+=в при някой от майкрочипските пикове e възможнa следнaтa оптимизация:
movf b,w // b-->W
addwf a,f // a=a+W
Междинен резултат няма изобщо!
То всъщност не е възможна, ами е възможно най-правилната. А ако изразът беше а=а+в, компилаторът би трябвало да изплюе следното:
movf b,w // b-->W
addwf a,w // W=W+a Ей го междинния резултат
movwf a // a=W
Един инструкшън в повече иде.
Понеже обаче защото, по дефоулт регистрите на ПЦ-тата са веке 32 битови като минимум, когато се използва тип по-малък от размера на регистъра, а операцията += е регистрова, както вече казах, следователно операндите (по пътя на логиката както казал оня милиционер) се преобразуват до int32 и резултатът - тоже, те плюе, че резултатът после ще бъде орязан от ляво. Защото резултатът не е тип шорт, ами е тип int32. Чисто логически. Когато е изписан пълния израз а=а+в, не се възприема (отново по пътя на логиката), че резултатът и операндите са int32, ами са си шорт - съответно варнингът липсва. В момента не ми идва на ум защо аджеба е сложено това напомняне...... ама може пък и да има смисъл от него.
По подразбиране (поне за мен) операциите от тип += или изобщо някаква_си_Аритм/Лог.операция=, са били първоначално замислени като регистрови такива. Всъщност реално оптимизация от гледна точка на код и бързодействие (при липса на фп копроцесор, пък и при наличието му май все тая) имаме само когато и двата операнда са не по-големи от регистъра на АЛУ-то който се ползва. И то за цели числа. И то ако инструкциите на процесора позволяват подобно нещо.
Примерно да кажем за едно ядро, което позволява резултата от операцията да не остане в акумулатора ( А/Лрегистър на процесора), ами да се запише директно в паметта, или когато са допустими операции регистър/регистър или памет/памет.
За а+=в при някой от майкрочипските пикове e възможнa следнaтa оптимизация:
movf b,w // b-->W
addwf a,f // a=a+W
Междинен резултат няма изобщо!
То всъщност не е възможна, ами е възможно най-правилната. А ако изразът беше а=а+в, компилаторът би трябвало да изплюе следното:
movf b,w // b-->W
addwf a,w // W=W+a Ей го междинния резултат
movwf a // a=W
Един инструкшън в повече иде.
Понеже обаче защото, по дефоулт регистрите на ПЦ-тата са веке 32 битови като минимум, когато се използва тип по-малък от размера на регистъра, а операцията += е регистрова, както вече казах, следователно операндите (по пътя на логиката както казал оня милиционер) се преобразуват до int32 и резултатът - тоже, те плюе, че резултатът после ще бъде орязан от ляво. Защото резултатът не е тип шорт, ами е тип int32. Чисто логически. Когато е изписан пълния израз а=а+в, не се възприема (отново по пътя на логиката), че резултатът и операндите са int32, ами са си шорт - съответно варнингът липсва. В момента не ми идва на ум защо аджеба е сложено това напомняне...... ама може пък и да има смисъл от него.
Редактирано от пopyчиk Pжeвckи на
Re: Integer promotions in C++ - странен warning.
А какъв е вица за пътя на логиката и милиционера? 
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Re: Integer promotions in C++ - странен warning.
Няма да го разказвам, щото рискувам да бъда глобен за досаждане с брадати вицове. Ще дам обаче няколко хинта, както е модерно да се казва.
Действащи лица:
1. Милиционер
2. Приятел на милиционера
3. Началник на милиционера
4. Аквариум
5. Любов към животните
6. Любов м/у еднакви полове
7. Логика
Тук веке сички требе да са се сетили (по пътя на логиката
)
Действащи лица:
1. Милиционер
2. Приятел на милиционера
3. Началник на милиционера
4. Аквариум
5. Любов към животните
6. Любов м/у еднакви полове
7. Логика
Тук веке сички требе да са се сетили (по пътя на логиката
Re: Integer promotions in C++ - странен warning.
Хаха, бе ти направо си го разказа...трябваше хинтовете да са малко по-така като хинтове 
Re: Integer promotions in C++ - странен warning.
Коментарите винаги трябва да са подробни и ясни 


Re: Integer promotions in C++ - странен warning.
кода горе не минава компилация с компилатор блондинка 1.3
Re: Integer promotions in C++ - странен warning.
Ясно... 
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.
Мечтата е мисъл, мисълта е идея, всяка идея се реализира. Аз не мечтая, а реализирам идеите си.