一段源码, Visual Studio 2019 上编译不成功, Linux 上可以

2021-03-04 10:02:20 +08:00
 commoccoom
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* unsigned long to string */
char * ultostr(unsigned long value, char * ptr, int base);

int main(void)
{
	char var[] = "0A84010000000301";
	unsigned long value = strtoul(var, NULL, 16);
    
    
	printf("value is %lu\n\n", value);

    char * str;
    ultostr(value, str, 16);

    printf("Received '%s'\n\n", str);

	return 0;
}

/* unsigned long to string */
char* ultostr(unsigned long value, char* ptr, int base)
{
    unsigned long t = 0, res = 0;
    unsigned long tmp = value;
    int count = 0;

    if (NULL == ptr)
    {
        return NULL;
    }

    if (tmp == 0)
    {
        count++;
    }

    while (tmp > 0)
    {
        tmp = tmp / base;
        count++;
    }

    ptr += count;

    *ptr = '\0';

    do
    {
        res = value - base * (t = value / base);
        if (res < 10)
        {
            *--ptr = '0' + res;
        }
        else if ((res >= 10) && (res < 16))
        {
            *--ptr = 'A' - 10 + res;
        }
    } while ((value = t) != 0);

    return(ptr);
}

VS2019 提示使用了未初始化的局部变量 str,但是 gcc 编译就没出问题,gcc 是 8.3.0

这是为啥?

4240 次点击
所在节点    C
29 条回复
ysc3839
2021-03-04 12:41:28 +08:00
第一个问题是指针变量未初始化就使用。
第二个问题是 unsigned long 在不同平台上长度不一致,建议改成 strtoull 。
commoccoom
2021-03-04 12:43:08 +08:00
@iyezi 这个对结果没有影响吧
CismonX
2021-03-04 12:45:04 +08:00
用 gcc/clang 编译的时候,加参数 -Wall -Wextra -Wpedantic 是基操,加上以后可以看到如下警告:

warning: variable 'str' is uninitialized when used here [-Wuninitialized]
felixcode
2021-03-04 13:01:06 +08:00
就该把 Linux 内核放到 Visual Studio 编译
fighte97
2021-03-04 16:05:50 +08:00
C#可以多用用 能搞懂很多 C/C++的坑
jim9606
2021-03-04 17:34:38 +08:00
局部变量没有初始化的话初值不一定为 0,指针好像也是这样的,所以 char*还是习惯初始化为 NULL 或者 malloc 。

如果需求定长 64 位的 int 类型,应该用 stdint.h 标头里的 uint64_t,在 printf/scanf 中用 inttypes.h 标头里的宏 PRIu64/SCNu64,如果是地址应该用 intptr_t/PRIiPTR/SCNiPTR
Rrobinvip
2021-03-04 21:27:28 +08:00
注意到你最后更正的地方还有一个致命问题,可能是因为要转换的 str 太短了没体现出来

你用 `int size = sizeof(Val)`, 然后给 str malloc 这么多空间。事实上无论你的 val 指向的 str 到底有多大,这个 size 永远都是 8,因为你得到的是一个 pointer 的大小,而不是实际 string 的长度。

我感觉你的想法是,看一下 val 这个 str 有多长,然后给 str malloc 这么多空间吧?

所以你应该用 `size_t size=strlen(Val)+1` ,然后再 malloc 。
ysc3839
2021-03-04 21:58:59 +08:00
@Rrobinvip 这里的 char var[] 是数组,sizeof 得到的是数组长度而不是指针长度。

#include <stdio.h>
int main()
{
char var[] = "0A84010000000301";
printf("%u", sizeof(var));
}

可以自行运行以上代码看看结果。
Rrobinvip
2021-03-04 22:02:55 +08:00
@ysc3839 学艺不精,受教了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/758288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX