| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | bitshift Fra : Troels Thomsen | 
  Dato :  27-06-02 20:10 |  
  |   
            Hej
 
 Hvilken type har:    værdi << antal_bits
 Og i hvilken grad afhænger det af processor/compiler ?
 
 Jeg løb ind i noget eksisterende kode der virkede og så sådan ud:
 (target: 8bit microcontroller, compiler: IAR fra '96)
 
 char value = something
 result = (unsigned long) (value<<24)
 
 Til et andet projekt med samme target, men nyere compiler, saksede vi koden,
 men det virkede ikke. Resultatet er altid nul fordi bitene bliver skuppet ud
 af registeret (gætter jeg på), hvorefter det bliver castet til long. Der
 skulle have stået sådan:
 
 char value = something
 result = ((unsigned long)value) << 24)
 
 På en PC og msvc 6 er det ligegyldigt hvad man gør, antageligt fordi char'en
 bliver lagt i et 32 bit register, og derefter skiftet op, således at bit'en
 ikke forsvinder. Eller sker der et automatisk cast (promotion?) idet
 compileren kan se at dette ikke kan være i en char? I så fald var det jo den
 ældste compiler der var den smarteste...
 
 mvh
 Troels
 
 
  
            
             |   |   
            
        
 
            
         
           Byrial Jensen (27-06-2002) 
         
	
            | Kommentar Fra : Byrial Jensen | 
  Dato :  27-06-02 22:04 |  
  |   
            Troels Thomsen <troels.thom4sen@stofanet.dk> skrev:
 > Hej
 > 
 > Hvilken type har:    værdi << antal_bits
 
 I C har udtrykket samme type som typen af "værdi".
 
 Bemærk at der er tale om udefineret adfærd hvis "antal_bits" er
 negativ eller større end eller lig med bredden af "værdi".
 
 > Og i hvilken grad afhænger det af processor/compiler ?
 
 Det afhænger det ikke af.
 
 > Jeg løb ind i noget eksisterende kode der virkede og så sådan ud:
 > (target: 8bit microcontroller, compiler: IAR fra '96)
 > 
 > char value = something
 > result = (unsigned long) (value<<24)
 
 Udtrykket (value<<24) har så typen char, og da typen char næppe har
 mere end 24 bit på en 8-bit-microcontroller, er der tale om
 udefineret adfærd. Dvs. at alt er tilladt.
 
 > Til et andet projekt med samme target, men nyere compiler, saksede vi koden,
 > men det virkede ikke. Resultatet er altid nul fordi bitene bliver skuppet ud
 > af registeret (gætter jeg på), hvorefter det bliver castet til long.
 
 Gættet er sikkert rigtigt, men alt muligt andet er som sagt også
 tilladt.
 
 > Der
 > skulle have stået sådan:
 > 
 > char value = something
 > result = ((unsigned long)value) << 24)
 
 Korrekt.
 
 > På en PC og msvc 6 er det ligegyldigt hvad man gør, antageligt fordi char'en
 > bliver lagt i et 32 bit register, og derefter skiftet op, således at bit'en
 > ikke forsvinder. Eller sker der et automatisk cast (promotion?) idet
 > compileren kan se at dette ikke kan være i en char?
 
 Nej, der sker ikke en automatisk typekonvertering. Men med
 udefineret adfærd kan alt tænkes. Hvis en bestemt oversætter har
 lyst til automatiske konverteringer, er det også tilladt.
 
 > I så fald var det jo den
 > ældste compiler der var den smarteste...
 
 En smart oversætter havde nægtet at oversætte det fejlbehæftede
 kode.
  
            
             |   |   
            
        
 
            
         
           Anders J. Munch (30-06-2002) 
         
	
            | Kommentar Fra : Anders J. Munch | 
  Dato :  30-06-02 11:27 |  
  |   
            "Byrial Jensen" <bjensen@nospam.dk> skrev:
 > > Hej
 > >
 > > Hvilken type har:    værdi << antal_bits
 >
 > I C har udtrykket samme type som typen af "værdi".
 
 C++: Når typen af 'vaerdi' er char så har udtrykket typen int[1],
 ganske som Richard forklarede, på grund af integral promotions. Et
 begreb jeg var overbevist om stammede fra C. Jeg er derfor tilbøjelig
 til at tro at du tager fejl. Kan du pege på en implementation hvor
 dette program udskriver '1'?
 
 #include <stdio.h>
 int main() { printf("%d", (int)sizeof((char)0 << 1)); }
 
 > Troels Thomsen <troels.thom4sen@stofanet.dk> skrev:
 > > Jeg løb ind i noget eksisterende kode der virkede og så sådan ud:
 > > (target: 8bit microcontroller, compiler: IAR fra '96)
 
 Jeg har prøvet at arbejde med en IAR compiler fra '96. Buggy as hell!
 Men de nye versioner er gode.
 
 - Anders
 
 [1] Teoretisk kan der findes implementationer hvor den er unsigned int.
 
 
 
  
            
             |   |   
            
        
 
            
         
            Byrial Jensen (30-06-2002) 
         
	
            | Kommentar Fra : Byrial Jensen | 
  Dato :  30-06-02 14:46 |  
  |   
            Anders J. Munch <andersjm@inbound.dk> skrev:
 > "Byrial Jensen" <bjensen@nospam.dk> skrev:
 >> >
 >> > Hvilken type har:    værdi << antal_bits
 >>
 >> I C har udtrykket samme type som typen af "værdi".
 > 
 > C++: Når typen af 'vaerdi' er char så har udtrykket typen int[1],
 > ganske som Richard forklarede, på grund af integral promotions. Et
 > begreb jeg var overbevist om stammede fra C. Jeg er derfor tilbøjelig
 > til at tro at du tager fejl.
 
 Jeg tog fejl. Du og Richard har ret. "værdi" udsættes for integral
 promotion, og resultatet har samme type som værdi _efter integral
 promotion_.
 
 > Kan du pege på en implementation hvor
 > dette program udskriver '1'?
 > 
 > #include <stdio.h>
 > int main() { printf("%d", (int)sizeof((char)0 << 1)); }
 
 Ja, alle implementationer hvor char og int samme størrelse.
 Og nej, jeg kender ingen konkrete implentationer hvor dette er
 tilfældet.
  
            
             |   |   
            
        
 
            
         
           Richard Flamsholt (29-06-2002) 
         
	
            | Kommentar Fra : Richard Flamsholt | 
  Dato :  29-06-02 00:35 |  
  |  
 
            "Troels Thomsen" <troels.thom4sen@stofanet.dk> skrev:
 >char value = something
 >result = ((unsigned long)value) << 24)
 >
 >På en PC og msvc 6 er det ligegyldigt hvad man gør, antageligt fordi char'en
 >bliver lagt i et 32 bit register, og derefter skiftet op, således at bit'en
 >ikke forsvinder.
 Når en char optræder som operand i et expression (som i fx c<<24) bliver
 dens type automatisk konverteret til int. For PC+MSVC6 er en int 32 bit
 og derfor virker det fint der.
 >I så fald var det jo den ældste compiler der var den smarteste...
 At koden virkede i den gamle compiler må skyldes enten
     a) den gamle compiler definerede int som mindst 32 bit, mens
        den nye compiler definerer (er indstillet til?) int som 16 bit
     b) int er 16 bits, men den gamle compiler beregnede fejlagtigt
        expressions i 32 bit mens den nye opfører sig korrekt
     c) koden har i virkeligheden aldrig virket (et gammelt ubrugt levn)
 -- 
 Richard Flamsholt
 richard@flamsholt.dk -  www.richard.flamsholt.dk
            
             |   |   
            
        
 
            
         
           Byrial Jensen (29-06-2002) 
         
	
            | Kommentar Fra : Byrial Jensen | 
  Dato :  29-06-02 17:34 |  
  |   
            Richard Flamsholt <richard@flamsholt.dk> skrev:
 > "Troels Thomsen" <troels.thom4sen@stofanet.dk> skrev:
 >>char value = something
 >>result = ((unsigned long)value) << 24)
 >>
 >>På en PC og msvc 6 er det ligegyldigt hvad man gør, antageligt fordi char'en
 >>bliver lagt i et 32 bit register, og derefter skiftet op, således at bit'en
 >>ikke forsvinder.
 > 
 > Når en char optræder som operand i et expression (som i fx c<<24) bliver
 > dens type automatisk konverteret til int. For PC+MSVC6 er en int 32 bit
 > og derfor virker det fint der.
 
 Undskyld jeg siger det, men det er noget vrøvl. Se min besvarelse
 for en nærmere forklaring.
 
 >>I så fald var det jo den ældste compiler der var den smarteste...
 > 
 > At koden virkede i den gamle compiler må skyldes enten
 > 
 >     a) den gamle compiler definerede int som mindst 32 bit, mens
 >        den nye compiler definerer (er indstillet til?) int som 16 bit
 >     b) int er 16 bits, men den gamle compiler beregnede fejlagtigt
 >        expressions i 32 bit mens den nye opfører sig korrekt
 >     c) koden har i virkeligheden aldrig virket (et gammelt ubrugt levn)
 
 Ad a) int er overhovedet ikke indblandet.
 Ad b) int er overhovedet ikke indblandet.
 Ad c) Her kommer du tættest på. Koden har aldrig været korrekt og
       giver udefineret adfærd. Der er ingen grund til at overveje
       hvilken konkret udefineret adfærd som en konkret oversætter
       giver. Udefineret adfærd bør altid undgås!
  
            
             |   |   
            
        
 
            
         
            Byrial Jensen (30-06-2002) 
         
	
            | Kommentar Fra : Byrial Jensen | 
  Dato :  30-06-02 14:46 |  
  |   
            Byrial Jensen <bjensen@nospam.dk> skrev:
 > Richard Flamsholt <richard@flamsholt.dk> skrev:
 >> 
 >> Når en char optræder som operand i et expression (som i fx c<<24) bliver
 >> dens type automatisk konverteret til int. For PC+MSVC6 er en int 32 bit
 >> og derfor virker det fint der.
 > 
 > Undskyld jeg siger det, men det er noget vrøvl.
 
 UPS! Det er mig der vrøvler. Det er rigtigt at en char i de fleste
 udtryk konverteres til int (eller unsigned int) før brugen, og at
 det normalt er typen af den eller de konverterede operander som
 afgør typen af resultatet.
 
 Undskyld fejlen og beskyldningen for at vrøvle når det i
 virkeligheden er mig som vrøvler!
 
 >> At koden virkede i den gamle compiler må skyldes enten
 >> 
 >>     a) den gamle compiler definerede int som mindst 32 bit, mens
 >>        den nye compiler definerer (er indstillet til?) int som 16 bit
 >>     b) int er 16 bits, men den gamle compiler beregnede fejlagtigt
 >>        expressions i 32 bit mens den nye opfører sig korrekt
 >>     c) koden har i virkeligheden aldrig virket (et gammelt ubrugt levn)
 
 Ja!
  
            
             |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |