Aracılığıyla paylaş


Derleyici uyarısı (düzey 2) C4146

unsigned türüne uygulanan birli eksi işleci, sonuç hala imzasız

İmzasız türler yalnızca negatif olmayan değerleri barındırabilir, bu nedenle birli eksi (olumsuzlama) genellikle işaretsiz bir türe uygulandığında anlamlı olmaz. hem işlenen hem de sonuç negatif değil.

Açıklamalar

Negatif bir tamsayı değişmez değerini ifade ettiğinizde, - değerin önünde bir tekli olumsuzlama işleci olarak ayrıştırılır. Derleyici, sayısal değeri ayrıştırdıktan sonra işlecini uygular. Sayısal değer işaretsiz tamsayı türünün aralığına uyuyorsa ancak karşılık gelen imzalı tamsayı türüne uymuyorsa, derleyici değeri işaretsiz olarak yorumlar. İmzasız bir değer, tekli olumsuzlama işleci tarafından değiştirilmez.

Bu uyarı genellikle -2147483648 veya long long en düşük int değer olan -9223372036854775808 değerini ifade etmeye çalıştığınızda oluşur. Bu değerler sırasıyla -2147483648 veya -9223372036854775808ll olarak yazılamaz. Bunun nedeni, derleyicinin ifadeyi iki aşamada işlemesidir: önce sayısal değeri ayrıştırıyor, ardından olumsuzlama işlecini uyguluyor. Örneğin, derleyici -2147483648 ayrıştırdığında şu adımları izler:

  1. 2147483648 sayısı değerlendirilir. 2147483647 en büyük int değerinden büyük olduğundan, ancak yine de bir unsigned intdeğerine sığdığından, 2147483648 türü olur unsigned int.

  2. İşaretsiz değere birli eksi uygulanır ve imzasız sonuç da 2147483648 olur.

Sonucun imzasız türü beklenmeyen davranışlara neden olabilir. Sonuç bir karşılaştırmada kullanılırsa, örneğin diğer işlenen bir olduğunda imzasız bir intkarşılaştırma kullanılabilir.

C4146'dan <limits.h> veya C++ eşdeğeri <climits>olan kullanarak INT_MIN LLONG_MIN önleyebilirsiniz. Bu değerlerin imzalı türleri vardır.

/sdl (Ek Güvenlik Denetimlerini Etkinleştir) derleyici seçeneği bu uyarıyı bir hataya yükseltir.

Örnek

Aşağıdaki örnek, derleyici C4146 uyarısı oluşturduğunda gerçekleşebilecek beklenmeyen davranışı gösterir:

// C4146.cpp
// compile with: /W2
#include <iostream>

void check(int i)
{
    if (i > -9223372036854775808ll)   // C4146
        std::cout << i << " is greater than the most negative long long int.\n";
}

int main()
{
    check(-100);
    check(1);
}

Bu örnekte, değişmez değer bir ll son eke sahip olsa ve olumsuzlama işleci uygulanmış olsa bile derleyici -9223372036854775808ll işaretinin kaldırıldığını dikkate alır. Karşılaştırma yapmak < için derleyici sessizce olarak olarak imzalı i olarak unsigned long long intyükselter. Beklenen ikinci satır olan 1 is greater than the most negative long long int, false olduğundan ((unsigned long long int)1) > 9223372036854775808ull yazdırılmaz.

Örneği düzeltmek için - 9223372036854775808ll değerini ekleyin <climits> ve olarak LLONG_MINdeğiştirin.

Ayrıca bkz.

Tekli olumsuzlama işleci (-)