Bu derleyici optimizasyonu bir hata, ya da tanımsız bir davranıştır?
Kod bu parça açıklayamam sinir bozucu bir hata var:
unsigned char bitmap[K_BITMAP_SIZE] = {0} ;
SetBit(bitmap, K_18); // Sets the bit #18 to 1
for(size_t i = 0; i < K_END; i)
{
if(TestBit(bitmap, i)) // true for 18
{
size_t i2 = getData(i); // for 18, will return 15
SetBit(bitmap, i2); // BUG: IS SUPPOSED TO set the bit #15 to 1
}
}
- Visual C 2010 tarihinde olur
- 32-bit ve 64-bit hem de inşa olur
- Sürüm oluşturur ("Hız (/O2)" olarak ayarlayın. yalnızca en üst düzeye çıkarmak olur
- Sadece Serbest "Boyutu (/O1)" olarak ayarlayın . en Aza indirmek ile inşa olmaz
- 5 ** getData fonksiyonu (varsayılan olarak, VC 2008 işlev satır içi değil, VC 2010 yaparken) sadece Visual C 2008 olur
- Döngü içinde kod aşağıda, muhtemelen büyük satır içi uygulaması nedeniyle verilen parça üzerinde olur
- Biz döngü kaldırmak ve doğrudan ilginç değeri (18) ayarlamak olmaz
Bonus bilgi:
1 - BenJ C, 2012, anlamı bu derleyici bir hata olabilir bu sorun, Visual görünmüyor yorumladı
Eğer Test//Set unsigned char
alçı eklersek 2 - ResetBit fonksiyonları, hata da kaybolur
size_t TestBit(const unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) & (1 << (unsigned char)((pos) & 7))) ; }
size_t SetBit(unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) |= (1 << (unsigned char)((pos) & 7))) ; }
size_t ResetBit(unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) &= ~(1 << (unsigned char)((pos) & 7))) ; }
Soru:
Bu hata kodu tanımsız davranış dayanır, ya da orada VC 2010 derleyici bazı böcek için olur mu?
Aşağıdaki kaynak-kendi kendine yeterli, ve en sevdiğiniz derleyici gibi derlenmiş olabilir:
#include <iostream>
const size_t K_UNKNOWN = (-1) ;
const size_t K_START = (0) ;
const size_t K_12 = (K_START 12) ;
const size_t K_13 = (K_START 13) ;
const size_t K_15 = (K_START 15) ;
const size_t K_18 = (K_START 18) ;
const size_t K_26 = (K_START 26) ;
const size_t K_27 = (K_START 27) ;
const size_t K_107 = (K_START 107) ;
const size_t K_128 = (K_START 128) ;
const size_t K_END = (K_START 208) ;
const size_t K_BITMAP_SIZE = ((K_END/8) 1) ;
size_t TestBit(const unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) & (1 << ((pos) & 7))) ; }
size_t SetBit(unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) |= (1 << ((pos) & 7))) ; }
size_t ResetBit(unsigned char * bits, size_t pos) { return (((bits)[(pos) >> 3]) &= ~(1 << ((pos) & 7))) ; }
size_t getData(size_t p_value)
{
size_t value = K_UNKNOWN;
switch(p_value)
{
case K_13: value = K_12; break;
case K_18: value = K_15; break;
case K_107: value = K_15; break;
case K_27: value = K_26; break;
case K_128: value = K_12; break;
default: value = p_value; break;
}
return value;
}
void testBug(const unsigned char * p_bitmap)
{
const size_t byte = p_bitmap[1] ;
const size_t bit = 1 << 7 ;
const size_t value = byte & bit ;
if(value == 0)
{
std::cout << "ERROR : The bit 15 should NOT be 0" << std::endl ;
}
else
{
std::cout << "Ok : The bit 15 is 1" << std::endl ;
}
}
int main(int argc, char * argv[])
{
unsigned char bitmap[K_BITMAP_SIZE] = {0} ;
SetBit(bitmap, K_18);
for(size_t i = 0; i < K_END; i)
{
if(TestBit(bitmap, i))
{
size_t i2 = getData(i);
SetBit(bitmap, i2);
}
}
testBug(bitmap) ;
return 0;
}
Bazı arka plan bilgileri: Başlangıçta:
- Test//Set fonksiyonları makrolar vardı ResetBit.
- sabitleri tanımlar
- endeksleri
long
int
da (Windows 32-bit, aynı boy var)
Gerekirse, (her iki yapılandırmaları için oluşturulan çevirici örneğin, g sorunun üstesinden nasıl update), en kısa sürede bir kaç bilgi daha ekleyeyim.
CEVAP
Bu kod iyileştirici bir hata değildir. Hem bu inlines getData() ve SetBit(). Kombinasyonu ölümcül görünüyor, 1 < değerini izini kaybeder;< ((pos) & 7) ve her zaman sıfır üretir.
Bu hata VS2012 oluşmaz. Geçici bir çözüm işlevlerinden biri inlined almak için değil zorlamak için. Kodu verilen, muhtemelen getData için bunu yapmak istiyorum():
__declspec(noinline)
size_t getData(size_t p_value)
{
// etc..
}
&; sorgu Select2 tanımsız hata" iç...
Neden bu tanımsız bir davranıştır?...
GCC C Linker hata: Tanımsız referans &...
Hata javac derleyici olarak eclipse ve...
İçinde bir değişken durum olmadığını b...