【问题标题】:Is it unsafe to pass an unsigned long to a function which uses a long?将 unsigned long 传递给使用 long 的函数是否不安全?
【发布时间】:2020-12-18 16:15:51
【问题描述】:

前言:我不能使用 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 是否不安全?如果是,我怎样才能使它工作?

编辑: 以下是我目前的使用方式:

unsigned long    val;
char            *hexa;

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

【问题讨论】:

  • 问题是您的 function 不能安全地与 signed long 一起使用:D
  • 只需使用sprintf()。这至少是多线程安全的,您发布的功能是不是。哎呀,您发布的那个不安全,因为后续使用会消除以前使用的价值。
  • 这个问题归结为“将无符号整数转换为有符号整数是否安全”(如果我们忽略不相关的问题)。答案可以在 C 标准 port70.net/~nsz/c/c11/n1570.html#6.3.1.3 中找到(否则,新类型是有符号的,并且值不能在其中表示;结果要么是实现定义的,要么引发实现定义的信号。)
  • 对于它的价值,这个功能只是塞满了“什么??不!”时刻。如果目标是将数字转换为字符串,请使用现有的库函数。这个问题在几十年前就已经解决了,并且在标准库中。
  • 继续阅读snprintf,因为这段代码需要真正的对话和干预。 %xl 做你想做的,然后做一些。

标签: c prototype unsigned


【解决方案1】:

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

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

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

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

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

"reduced modulo 2^N" - 基本上减去 2^N 直到值在范围内。因此,如果您有 32 位 longs 和 (long)(unsigned long)4294967196ul,则从该值中减去 2^32,它等于 (long)-100

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

正确处理负数。

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

另外,(unsigned long)va_arg(*list, void *);void* 指针值转换为 unsigned long (?)。很可能您希望 va_arg(list, unsigned long) - 从参数中获取 unsigned long

【讨论】:

  • 我正在重新编码 printf 函数,我使用的是 %p 格式。这就是我使用 va_arg(list, void*) 来获取指针地址的原因。我被告知然后将其转换为无符号长。
猜你喜欢
  • 2018-10-15
  • 1970-01-01
  • 2016-09-29
  • 2016-07-29
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 2022-12-20
  • 2015-06-23
相关资源
最近更新 更多