一段源码, 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

这是为啥?

4227 次点击
所在节点    C
29 条回复
codehz
2021-03-04 10:06:06 +08:00
好家伙,你这 str 准备存哪里,编译不炸运行时炸的节奏(没炸也是运气好)
commoccoom
2021-03-04 10:07:38 +08:00
@codehz 但是为啥 gcc 没报错😂
venicejack
2021-03-04 10:09:03 +08:00
gcc 肯定是报 warning 了,编译成功不代表运行不 core
rocksolid
2021-03-04 10:11:03 +08:00
侧面印证了 Visual Studio 果然是宇宙第一 IDE
aloxaf
2021-03-04 10:11:26 +08:00
因为你没加 `-Wall -Wextra -Werror`,加了 gcc 就也会拒绝编译了(
ReVanTis
2021-03-04 10:17:39 +08:00
关掉 sdl 检查或者去掉编译器的 /sdl 选项,msvc 也可以编译过
ReVanTis
2021-03-04 10:19:03 +08:00
@ReVanTis

https://stackoverflow.com/questions/18559425/how-to-ignore-uninitialized-variable-error-in-msvc

用这个宏应该也可以
#pragma warning (disable: 4703)

在某些特殊场景下,不排除需要这么做的可能性
IDAEngine
2021-03-04 10:24:25 +08:00
还是 VS 专业些
commoccoom
2021-03-04 10:27:47 +08:00
https://gist.githubusercontent.com/yloveyy/77bf89ff4b249e67185d99de81d3a1d7/raw/c923dba61b4962c66a3ee5faf60bfeefbd632a28

修改了一下,加了
int size = sizeof(var);
char * str = malloc(size + 1);

但是 Windows 平台和 Linux 平台运行的结果不一样,Linux 运行符合预期,但是 Windows 结果

value is 4294967295

Received 'FFFFFFFF'

为啥。。。。
pisc
2021-03-04 10:30:44 +08:00
楼上都答不到点上来啊

@commoccoom 因为这个程序本来就是合法的,没有错,但这么用很危险,所以 vs 默认把这种“警告级别”升级为了“编译错误”,因为本身程序是合法的,所以 GCC 编译成功是没问题的,但一般会有警告信息,GCC 也可以配置成
xdeng
2021-03-04 10:31:38 +08:00
指针变量 除非你有十足的把握 否则应该给默认值 null
aloxaf
2021-03-04 10:42:12 +08:00
@commoccoom 盲猜你 Windows 是 32 位的(或者默认编译 32 位程序
moonmagian
2021-03-04 10:47:19 +08:00
局部变量的初始值是和 os 相关的随机值,gcc 编译能跑只是因为随机的地址恰好可读可写而且不会覆盖其他内存里的东西。即使偶尔能跑,多跑几次或者换台机器跑就不一定了...
aloxaf
2021-03-04 10:48:26 +08:00
newmlp
2021-03-04 10:58:07 +08:00
说明 gcc 就是辣鸡编译器
yuruizhe
2021-03-04 11:12:07 +08:00
@newmlp 好家伙,Apache 沉默 GUN 流泪
402124773
2021-03-04 11:47:19 +08:00
@yuruizhe
直呼好家伙就可以了
iyezi
2021-03-04 12:27:39 +08:00
@commoccoom #9 可能 sizeof 求出来的是一个指针的 size 吧。你想写的是不是 strlen ?
littlewing
2021-03-04 12:38:54 +08:00
说明 linux 辣鸡,windows 天下第一
翻译一下就是 linus 辣鸡,印度啊三天下第一
littlewing
2021-03-04 12:41:02 +08:00
@littlewing 对了,还得加上 GNU 辣鸡,所以 RMS 辣鸡

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

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

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

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

© 2021 V2EX