首页 > 解决方案 > 将 unsigned long 传递给使用 long 的函数是否不安全?

问题描述

前言:我不允许使用 C 库中的任何函数

我有这个功能:

char *to_base(long nbr, char *base)
{
    static char buffer[50];
    char    *ptr;
    int     base_len;

    ptr = &buffer[49];
    *ptr = 0;
    base_len = ft_strlen(base);
    while (nbr != 0)
    {
        *--ptr = base[nbr % base_len];
        nbr /= base_len;
    }
    return (ptr);
}

正如我们所见,这需要很长时间。在我的程序中,我有一个无符号长整数,我必须将其转换为十六进制值。在这个函数中传递unsigned long是否不安全?如果是,我怎样才能使它工作?

编辑:这是我目前使用它的方式:

unsigned long    val;
char            *hexa;

val = (unsigned long)va_arg(*list, void *);
hexa = to_base(val, "0123456789abcdef");

标签: cprototypeunsigned

解决方案


在这个函数中传递 unsigned long 是否不安全?

它是“安全的”,因为该程序不会格式化您的硬盘驱动器或引发另一场世界大战。

传递的函数参数被转换为参数类型。无符号值将转换为有符号值。今天所有的架构都使用二进制补码,很容易预测结果。您的编译器应该记录行为,例如。在gcc 实现中定义的 beahvior

当值无法在该类型的对象中表示时,将整数转换为有符号整数类型的结果或引发的信号(C90 6.2.1.2、C99 和 C11 6.3.1.3)。

为了转换为宽度为 N 的类型,该值以 2^N 为模减少到该类型的范围内;没有发出信号。

“减少模 2^N” - 基本上减去 2^N 直到值在范围内。因此,如果您有 32 位longs 并且有(long)(unsigned long)4294967196ul,那么您从值中减去 2^32 并且它等于(long)-100.

如果是,我怎样才能使它工作?

正确处理负数。

并为无符号和有符号数字编写单独的函数。

还将指针值转换为(unsigned long)va_arg(*list, void *);(?)。很可能你想要-从论点中获取。void*unsigned longva_arg(list, unsigned long)unsigned long


推荐阅读