printf的相同代码,不同的输出?

时间:2017-01-06 13:32:43

标签: c struct printf

我有一个结构:

typedef struct cbor {
  cbor_type type;

  uint64_t length; //x2 for maps

  struct cbor* child;
  struct cbor* next;
  struct cbor* parent;

  union {
    const uint8_t* bytes;
    long sint;
    uint64_t uint;
    double real;
  } value;
} cbor;

我使用malloc初始化一个指向cbor的指针,并将length设置为0,并将uint和sint的值设置为1,并键入CBOR_INTEGER。

我有一个应该打印有关cbor struct的信息的函数:

void cbor_print_item(cbor* item){
    os_printf("c2 = %d %d %d\n", item->value.sint, item->value.uint, item->length);

    switch(item->type){
        case CBOR_INTEGER:
            os_printf("type:integer\nsval:%d\nuval:%d\nlength:%d\n", item->value.sint, item->value.uint, item->length);
            os_printf("type:integer\n");
            os_printf("sval:%d\n", item->value.sint);
            os_printf("uval:%d\n", item->value.uint);
            os_printf("length:%d\n", item->length);
            break;
        case CBOR_STRING:
            os_printf("type:\tstring\n");
            os_printf("val:\t%s\n", item->value.bytes);
            os_printf("length:\t%d\n", item->length);
            break;
        case CBOR_REAL:
            os_printf("type:\treal\n");
            os_printf("length:\t%d\n", item->length);
            os_printf("val:\t%f\n", item->value.real);
            break;
        default:
            os_printf("error!\n");
    }
}

但是,我没有得到预期的输出。 printf在开关中的输出应该是相同的,对吗? 我的输出是:

c2 = 1 1 0
type:integer
sval:1
uval:1
length:0
type:integer
sval:1
uval:144
length:144

我正在编写espressif的代码,因此“os_printf”,据我所知,它的工作方式是“printf”。

我真的很困惑,不知道为什么会这样。

编辑1:我知道我不应该长期使用“%d”和uint64。 问题是为什么产出不同? 我不会更改打印之间的值,因此应打印相同的值。

编辑2:这个问题不是关于联合,它们的初始化,打印uint64或更长的最佳方式。

问题是为什么

os_printf("type:integer\nsval:%d\nuval:%d\nlength:%d\n", item->value.sint, item->value.uint, item->length);

打印

type:integer
sval:1
uval:1
length:0

    os_printf("type:integer\n");
    os_printf("sval:%d\n", item->value.sint);
    os_printf("uval:%d\n", item->value.uint);
    os_printf("length:%d\n", item->length);

打印

type:integer
sval:1
uval:144
length:144

2 个答案:

答案 0 :(得分:4)

您有未定义的行为,因为您尝试使用uint64_t格式打印%dprintf(以及采用可变数量参数的其他函数)需要知道参数的类型(和大小)。它从格式说明符中获取此信息。由于您提供了%d而不是正确的格式,因此它尝试阅读int而不是uint64_t。请参阅this作为示例。

答案 1 :(得分:0)

使用sprintf(format, val1, val2)将参数堆栈上的val1和val2放到sprintf上,然后sprintf将根据格式字符串从该堆栈中获取值,格式字符串盲目地在值上运行,而不知道实际大小。 所以在quintessenz:未定义的行为