SORU
9 EYLÜL 2013, PAZARTESİ


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
9 EYLÜL 2013, PAZARTESİ


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 bir long 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 intunsigned int17. [...]

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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AFISHAL

    AFISHAL

    7 Mart 2009
  • apenney888

    apenney888

    27 EKİM 2010
  • Tomas N

    Tomas N

    14 Kasım 2010