2013-01-25 43 views
7

是什麼strlcpy.c之所以參數複製到本地變量:爲什麼要將函數參數複製到局部變量中?

size_t 
strlcpy(char *dst, const char *src, size_t siz) 
{ 
    char *d = dst; 
    const char *s = src; 
    size_t n = siz; 

    /* Copy as many bytes as will fit */ 
    if (n != 0) { 
     while (--n != 0) { 
      if ((*d++ = *s++) == '\0') 
       break; 
     } 
    } 

    /* Not enough room in dst, add NUL and traverse rest of src */ 
    if (n == 0) { 
     if (siz != 0) 
      *d = '\0';  /* NUL-terminate dst */ 
     while (*s++) 
      ; 
    } 

    return(s - src - 1); /* count does not include NUL */ 
} 

更新

我增加了身體。

回答

5

一個非常普遍的原因是變量在函數中被修改,然後在一個表達式中與參數一起使用。

例如,該功能可能修改變量n,並且稍後進行例如return siz - n;

代碼SIZ和src其餘
+0

@SperanskyDanil因爲該指針也可能被修改。想'while(...){* d ++ = * s ++; }' –

1

實際需要計算一些東西:

/* Not enough room in dst, add NUL and traverse rest of src */ 
if (n == 0) { 
    if (siz != 0) 
     *d = '\0';  /* NUL-terminate dst */ 
    while (*s++) 
     ; 
} 

return(s - src - 1); /* count does not include NUL */ 

但我不明白爲什麼DST被複制到本地。也許只是爲了對稱。

1

至少對於src參數,它用於計算要返回的長度。該函數的最後一行顯示:

return(s - src - 1); 

dst參數方面,它實際上沒有必要的,但它可能已經一致性完成。這可能並不重要,因爲體面的優化編譯器可能不會受到這個看似額外的變量的影響。

+1

「不必要的」掃描是不必要的。 'strl *'功能非常精心設計。 [你可以閱讀論文](http://static.usenix.org/event/usenix99/full_papers/millert/millert.pdf)。相關部分是:「與snprintf()具有相同語義的返回值是更好的選擇,因爲它使得程序員在截斷檢測和恢復方面具有最大的靈活性。」 – Art

+0

@藝術,這是一個很好的觀點,起初我沒有意識到它被指定返回_source_的長度而不是複製的字符數。刪除了我的錯誤假設。 – paxdiablo

1

對於dstd,我想,只是爲了simmetry。對於其他變量,它們在「代碼」中用於初始值和更新值。

0
size_t 
strlcpy(char *dst, const char *src, size_t siz) 
{      ^-------------------------->constant so must not be modified. that's why a temp variable is needed for modification.  
    char *d = dst;  <-- useless may be. 
    const char *s = src; 
    size_t n = siz;  

    /* Copy as many bytes as will fit */ 
    if (n != 0) {   
     while (--n != 0) { 
      if ((*d++ = *s++) == '\0') 
       break; 
     } 
    } 

    /* Not enough room in dst, add NUL and traverse rest of src */ 
    if (n == 0) {     <-- new n arg. 
     if (siz != 0)    <--- original siz arg 
      *d = '\0';  /* NUL-terminate dst */ 
     while (*s++) 
      ; 
    } 

    return(s - src - 1); /* count does not include NUL */ <-- using the original and modified values of s and src together. 
} 
+0

嘿請告訴關於無用的? – Arpit

相關問題