[英]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.