免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3445 | 回复: 9
打印 上一主题 下一主题

[函数] memset定义的问题以及dietlibc库中memcpy实现是不是有问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-02-09 23:20 |只看该作者 |倒序浏览
本帖最后由 wtan 于 2010-02-10 13:12 编辑

memset是这样定义的:
void* memset(void *, int, size_t count)

为什么不定义成这样呢?
void* memset(void *, char, size_t count)
这样不是更贴切一些吗?


在dietlibc这个库中memset是这样实现的:
void* memset(void * dst, int s, size_t count) {
    register char * a = dst;
    count++;        /* this actually creates smaller code than using count-- */
    while (--count)
        *a++ = s;
    return dst;
}

register char * a = dst;
上面这一句居然没有进行强制转换。
问一下,这样行不行,dietlibc代码的质量究竟怎样?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2010-02-09 23:22 |只看该作者
代码质量不怎样,memset 唯一要求就是快

论坛徽章:
0
3 [报告]
发表于 2010-02-10 12:04 |只看该作者

像memcpy采用了比较高效率的拷贝方法,memmove、memset之类的只是采用常规的方法,不知为什么要以它们区别对待,要是有说明文档就好了。

论坛徽章:
0
4 [报告]
发表于 2010-02-10 13:01 |只看该作者
C语言中char会自动提升为int,也许前人为了避免此种隐式类型提升,才这样做的吧!猜的!

论坛徽章:
0
5 [报告]
发表于 2010-02-10 13:10 |只看该作者
本帖最后由 wtan 于 2010-02-10 13:14 编辑

#define UNALIGNED(x,y) (((unsigned long)x & (sizeof (unsigned long)-1)) ^ ((unsigned long)y & (sizeof (unsigned long)-1)))

#define STRALIGN(x) (((unsigned long)x&3)?4-((unsigned long)x&3):0)

void *
memcpy (void *dst, const void *src, size_t n)
{
    void           *res = dst;
    unsigned char  *c1, *c2;
#ifdef WANT_SMALL_STRING_ROUTINES
    c1 = (unsigned char *) dst;
    c2 = (unsigned char *) src;
    while (n--) *c1++ = *c2++;
    return (res);
#else
    int             tmp;
    unsigned long  *lx1 = NULL;
    const unsigned long *lx2 = NULL;

    if (!UNALIGNED(dst, src) && n > sizeof(unsigned long)) {

        if ((tmp = STRALIGN(dst))) {
            c1 = (unsigned char *) dst;
            c2 = (unsigned char *) src;
            while (tmp-- && n--)
                *c1++ = *c2++;
            if (n == (size_t) - 1)
                return (res);
        }

        lx1 = (unsigned long *) dst;
        lx2 = (unsigned long *) src;

        for (; n >= sizeof(unsigned long); n -= sizeof(unsigned long))
            *lx1++ = *lx2++;
    }

    if (n) {
        c1 = (unsigned char *) (lx1?lx1:dst);
        c2 = (unsigned char *) (lx1?lx2:src);
        while (n--)
            *c1++ = *c2++;
    }

    return (res);
#endif
}


上面是dietlibc库中memcpy函数的原代码,如果两个地址都是对齐的,或者都没有对齐并且相差的数量是不一样的,程序是没有问题的,但是如果两个地址没有对齐并且相差的数量一样,比如一个地址是0x0012ff41,一个地址是0x0012ff61,这个时候就会得到错误的结果,请各位分析一下,是不是这样?或者是我没看明白?

论坛徽章:
0
6 [报告]
发表于 2010-02-10 16:08 |只看该作者
没有人感兴趣啊,

论坛徽章:
0
7 [报告]
发表于 2010-02-10 16:11 |只看该作者
C语言中char会自动提升为int,也许前人为了避免此种隐式类型提升,才这样做的吧!猜的!
jtkk 发表于 2010-02-10 13:01



    有道理,反正是要占用这么多空间的。

论坛徽章:
0
8 [报告]
发表于 2010-02-10 16:36 |只看该作者
C 语言的 character literal 是 int 类型。你看 getchar() 的返回值也是 int。

论坛徽章:
0
9 [报告]
发表于 2010-02-10 17:42 |只看该作者
C 语言的 character literal 是 int 类型。你看 getchar() 的返回值也是 int。
langue 发表于 2010-02-10 16:36



   是啊,好多函数都是这样。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
10 [报告]
发表于 2010-02-10 17:53 |只看该作者
其实还是因为C标准规定了C的字面字符常量是个int的缘故……C++就不是这样……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP