簡體   English   中英

內聯函數作為C中的參數傳遞時會發生什么?

[英]What happens when an inline function is passed as a parameter in C?

今天我編寫了一些C代碼來使用帶有自定義比較器功能的快速排序對結構數組進行排序,以確定它們的排序。

起初我用調用比特函數編寫它,硬編碼到quicksort函數中。 然后我想也許將該函數作為參數傳遞給通用的快速排序函數會更好。

在我原來的代碼中,我已經將比較器函數聲明為inline 在我的新代碼中,我保留了inline聲明,即使這對我來說沒有多大意義,因為函數是作為參數傳遞的。 但是,編譯器沒有抱怨!

我的問題是: inline聲明在這里有任何影響,還是僅僅是對編譯器的建議被忽略了?

原始代碼:

typedef struct _CGRect {
    CGPoint origin;
    CGSize size;
} CGRect;

typedef enum _NSComparisonResult {
     NSOrderedAscending = -1,
     NSOrderedSame,
     NSOrderedDescending
} NSComparisonResult;

static inline NSComparisonResult CGRectCompareRowsFirst(CGRect r1, CGRect r2)
{
    if (r1.origin.y < r2.origin.y)
        return NSOrderedAscending;
    else if (r1.origin.y > r2.origin.y)
        return NSOrderedDescending;
    else
    {
        if (r1.origin.x < r2.origin.x)
            return NSOrderedAscending;
        else if (r1.origin.x > r2.origin.x)
            return NSOrderedDescending;
        else
            return NSOrderedSame;
    }
}

static void CGRectQuicksortRowsFirst(CGRect *left, CGRect *right)
{
    if (right > left) {
        CGRect pivot = left[(right-left)/2];
        CGRect *r = right, *l = left;
        do {
            while (CGRectCompareRowsFirst(*l, pivot) == NSOrderedAscending) l++;
            while (CGRectCompareRowsFirst(*r, pivot) == NSOrderedDescending) r--;
            if (l <= r) {
                CGRect t = *l;
                *l++ = *r;
                *r-- = t;
            }
        } while (l <= r);
        CGRectQuicksortRowsFirst(left, r);
        CGRectQuicksortRowsFirst(l, right);
    }
}

static void CGRectSortRowsFirst(CGRect *array, int length)
{
    CGRectQuicksortRowsFirst(array, array+length-1);
}

新代碼:

static inline NSComparisonResult CGRectCompareRowsFirst(const void *s1, const void *s2)
{
    CGRect r1 = *(CGRect *)s1, r2 = *(CGRect *)s2;

    if (r1.origin.y < r2.origin.y)
        return NSOrderedAscending;
    else if (r1.origin.y > r2.origin.y)
        return NSOrderedDescending;
    else
    {
        if (r1.origin.x < r2.origin.x)
            return NSOrderedAscending;
        else if (r1.origin.x > r2.origin.x)
            return NSOrderedDescending;
        else
            return NSOrderedSame;
    }
}

static void quick(CGRect *left, CGRect *right, NSComparisonResult(*f)(const void *, const void *))
{
    if (right > left) {
        CGRect pivot = left[(right-left)/2];
        CGRect *r = right, *l = left;
        do {
            while (f(&*l, &pivot) == NSOrderedAscending) l++;
            while (f(&*r, &pivot) == NSOrderedDescending) r--;
            if (l <= r) {
                CGRect t = *l;
                *l++ = *r;
                *r-- = t;
            }
        } while (l <= r);
        quick(left, r, f);
        quick(l, right, f);
    }
}

static void CGRectSortRowsFirst(CGRect *array, int length)
{
    quick(array, array+length-1, CGRectCompareRowsFirst);
}

內聯只是對編譯器的推薦,可以忽略。 這可能由於多種原因而發生,例如,如果函數太復雜而無法安全地內聯。 如果將它作為參數傳遞給上面的函數,編譯器將創建非內聯版本,其地址將傳遞給函數。

編譯器可能仍然可以內聯函數 - 例如,在代碼生成期間,編譯器可以利用內聯函數提示通過函數指針替換調用僅擴展函數; 我不確定當前的編譯器是否會這樣做。

內聯和非內聯版本可以並且經常在一個編譯的程序中共存。

'inline'關鍵字只是一個編譯器標志,告訴它以不同的方式處理它,因為它將復制函數體並將其替換為實際的函數調用。 如果您有一個小函數可以在代碼中的許多位置重用,則可以提高性能。 使用存取器和修改器是一件很好的事情。 在你的情況下,我認為你可以保持原樣。 你沒有做任何沉重的事情。 差異很可能不明顯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM