Neden bu tanımsız bir davranıştır?
23* *cevabım bu işlevi oldu:
inline bool divisible15(unsigned int x)
{
//286331153 = (2^32 - 1) / 15
//4008636143 = (2^32) - 286331153
return x * 4008636143 <= 286331153;
}
Mükemmel hiç çalışmıyor VS2008 derleyici, here ancak benim makine üzerinde çalıştı.
Herkesin bir fikri olacak, neden ben farklı Derleyiciler farklı sonuçlar elde ediyor mu? 4* *taşma tanımsız davranış değil.
ÖNEMLİ NOT:bazı onaylandı testinden sonra 15 bölüm geri kalanı alarak daha hızlı. (Ancak tüm Derleyiciler değil)
CEVAP
Tanımsız Davranış değil, sadece C89 ve C99 arasında C dili standart bir son dakika değişikliği oldu.
İçinde C89, tamsayı sabitleri gibi 4008636143 o yok uygun bir int
long int
ama uygun bir unsigned int
imzasız, ama C99, onlar da long int
long long int
(bağlı olarak hangisi en küçük bir tutabileceğini değeri). Sonuç olarak, ifadeler yanlış cevap sonucu 64 bit ile değerlendirildi.
Visual Studio C89 bir derleyici ve C89 davranış oluşur, ama bu İdeone bağlantı C99 modda derleme.
Bu GCC ile -Wall
kullanarak derleme: daha belirgin hale gelir
test.c: In function ‘divisible15’:
test.c:8:3: warning: this decimal constant is unsigned only in ISO C90
C89 §3.1.3.2:
Bir tamsayı sabit türüyle ilgili ilk liste değerini temsil edilebilir. Ondalık Unsuffixed: int, long int, işaretsiz long int; unsuffixed sekizlik veya onaltılık: int, imzalanmamış int, long int, işaretsiz long int; [...]
C99 §6.4.4.1/5-6:
5) bir tamsayı sabiti hangi değeri olabilir ilgili listenin ilk temsil edilmesi.
Suffix | Decimal Constant | Octal or Hexadecimal Constant ------- ------------------ ------------------------------ none | int | int | long int | unsigned int | long long int | long int | | unsigned long int | | long long int | | unsigned long long int ------- ------------------ ------------------------------ [...]
Bir tamsayı sabit bir olamaz onun listesinde herhangi bir türünü temsil 6), olabilir genişletilmiş tamsayı türü değeri temsil edebilir genişletilmiş tamsayı yazın. Tüm eğer sabit listesinde türleri imzalanmış, uzun tamsayı türü imzalanır. [...]
Bütünlüğü için, C 03 aslında bir tamsayı sabit long int
sığmayacak kadar büyük olduğu için Tanımsız Davranış var. C 03 §2.13.1/2:
Bir tamsayı hazır bilgi türü, form, değer ve sonek kendi bağlıdır. Ondalık ve hiçbir sonek varsa, vardır bu tür hangi değerini temsil edilebilir:
int
,long int
; eğer değer gösterilemez birlong int
, davranış tanımsızdır. Sekizlik veya onaltılık ve hiçbir sonek varsa, vardır bu tür hangi değerini temsil edilebilir ilk: , , *,unsigned long int
*long int
unsigned int
17. [...]
C 11 davranış C99, C 11 §2.14.2/3 aynıdır.
Emin olmak için kodu davranır sürekli derlenmiş olarak da C89, C99, C-03 ve C-11, basit bir düzeltme yapmak için sürekli 4008636143 imzasız tarafından suffixing ile u
4008636143u
.
Neden bu tanımsız bir davranıştır?...
Neden ve'boş ve tanımsız arasında...
Neden bu (kullanarak ) tanımsız davran...
Neden bu döngü üretmek "uyarı: yi...
= 1 tanımsız davranışlara neden bir [[...