2013-01-25 40 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

相关问题