Bu kod

2015-08-13 45 views
6

anlamına gelir. Bir kod parçası buldum. Ben bunu anlamıyorum. Görünüşe göre __rem değişkeni işe yaramaz. Satır aşağıda henüz yararlı işler yapmaz:Bu kod

(void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ 

bütün kod segmenti aşağıdaki gibidir:

#define do_div(n,base) do{    \ 
    uint32_t __base = (base);   \ 
    uint32_t __rem;     \ 
    (void)(((typeof((n)) *)0) == ((uint64_t *)0)); \ 
    if (((n) >> 32) == 0) {   \ 
     __rem = (uint32_t)(n) % __base;  \ 
     (n) = (uint32_t)(n)/__base;  \ 
    } else      \ 
     __rem = __div64_32(&(n), __base); \ 
    __rem;      \ 
}while(0) 
/* Wrapper for do_div(). Doesn't modify dividend and returns 
* the result, not reminder. 
*/ 
static inline uint64_t lldiv(uint64_t dividend, uint32_t divisor) 
{ 
    uint64_t __res = dividend; 
    do_div(__res, divisor); 
    return(__res); 
} 

Neden yararsız kod burada?

+1

derleyici akıl denetimi? – EOF

+1

Yine, lütfen araç zinciri hakkında bilgi verin. Bu açıkça bir derleyici içseldir (tanımlayıcılarda çift-altçizgiler). – Quentin

+0

Bu uboot dosyasındaki div64.h dosyasından. Kopyaladım ve ilk başta iyi çalışıyor. Ama ben RVDS 5.01 ile derlediğimde. Derleyici, "ifadenin etkisiz" olduğundan şikayetç[email protected] – user1651758

cevap

12

1. (void)(((typeof((n)) *)0) == ((uint64_t *)0));

Linux/include/asm-generic/div64.h bakınız:

gereksiz işaretçi karşılaştırın olan orada tür güvenliği kontrol etmek için (n 64bit olmalıdır)

Örnek:

nint olmalı, ancak

void main() 
{ 
    short n; 
    (void)(((typeof((n)) *)0) == ((int *)0)); 
} 

short Biz uyarı olsun: gcc -o main main.c

Derleyici sürümü: comparison of distinct pointer types lacks cast

ile Derleyen gcc (GCC) 4.9.2 20141101 (Red Hat 4.9.2-1)

Sonuç:

İşaretçi karşılaştırması işe yaramıyor. do_div() değişkenine iletilen iletinin yanlış türde olması durumunda bir uyarı oluşturur.

2. __rem

parantezi ile çevrelenmiş kod gcc deyim-ifadeler olduğunu. __rem, do_div()'un geri dönüş değeridir.

Örnek:

#include <stdio.h> 

#define do_div(n,base) ({ \ 
    int __rem = n % base; \ 
    n /= base;    \ 
    __rem;     \ 
}) 

int main() 
{ 
    int a = 9; 
    int b = 2; 
    int c = 0; 

    printf("%i/%i = ", a, b); 
    c = do_div(a, b); 
    printf("%i, reminder = %i\n", a, c); 
    return 0; 
} 

Çıkış: 9/2 = 4, reminder = 1 Yukarıdaki örnekte

, c = do_div(a, b)c = ({int rem = a % b; a /= b; rem;}) eşdeğerdir.

Sonuç:

__rem o do_div() ait "dönüş değeri" dir yararsız değildir.

+0

Bunun varsayılan olarak bir uyarı üretmesi gariptir, gayet meşrudur: 'C11 taslak standart: 6.3.2.3 İşaretçiler 4 [...] Herhangi bir iki boş gösterici eşittir [...]' yi karşılaştırır. – EOF

+0

Oh, gcc 4.8.4'ümde de bir uyarı veriyor. Sadece -Wall' ya da -Wextra' ya da bunun gibi bir şey gerektirmediğine şaşırdım. – EOF

+0

@EOF, eşit * sonra * dönüşümün aynı türe göre karşılaştırılacağını söylüyor. Bununla birlikte, aynı türe dönüştürme, bu durumda bir döküm gerektirir. (C11 6.5.8/2) –