小编Mar*_*ton的帖子

以便携方式检索传递给variadic函数的int32_t

7.16.1.1 2描述va_arg如下(强调我的):

如果没有实际的下一个参数,或者type与实际的下一个参数的类型不兼容(根据默认参数提升而提升),则行为是未定义的,除了以下情况:

  • 一种类型是有符号整数类型,另一种类型是相应的无符号整数类型,并且该值可在两种类型中表示;
  • 一种类型是指向void的指针,另一种是指向字符类型的指针.

现在我的理解似乎6.5.2.2(函数调用)与我没有矛盾,虽然我可能错了,默认促销是:

  • charintunsigned(指定实施)
  • signed charint
  • unsigned charunsigned
  • shortint
  • unsigned shortunsigned
  • floatdouble

当你知道传递给它的确切的底层类型时,这一切都很好,花花公子va_list(除了char,因为它的签名是实现指定的,所以AFAIK无法进行便携式检索).

当你期望将类型<stdint.h>传递给你时,它会变得更加复杂va_list.

  • int8_t并且int16_t,通过逻辑极限观察来扣除,保证被提升或已经是类型int.然而,依靠我原来的"逻辑"极限观察是非常可疑的,所以我正在寻求你(以及标准)对这个演绎的确认(我可能会遗漏一些我甚至都不知道的角落情况).
  • 这同样适用于uint8_tuint16_t,除基础类型是unsigned
  • int32_t 可能会也可能不会晋升为int.它可能大于,小于或完全相同int.同样适用于uint32_t但是unsigned.如何移植检索int32_tuint32_t传递给va_list换句话说,如何确定if int32_t …

c type-conversion variadic-functions integer-promotion language-lawyer

9
推荐指数
1
解决办法
631
查看次数

当int32_t是扩展整数类型且int是32位补码标准整数类型时,(INT32_MIN + 1)是什么

想象一下这种情况.int32_t是一个扩展的整数类型,它以二进制补码表示(作为int32_t要表示的标准).这意味着INT32_MIN-2147483648(0x80000000).

同时int标准整数类型,它以一个补码表示(标准允许).这意味着INT_MIN-2147483647.

现在纠正我,如果我错了,但我认为两种类型都有相同的宽度,这意味着,根据6.3.1.1.1(强调我的):

任何标准整数类型的等级应大于具有相同宽度的任何扩展整数类型的等级.

所以排名int32_t低于int.

现在6.3.1.8(通常的算术转换)说(强调我的):

<...>否则,将对两个操作数执行整数提升.然后将以下规则应用于提升的操作数:如果两个操作数具有相同的类型,则不需要进一步转换.否则,如果两个操作数都具有有符号整数类型或两者都具有无符号整数类型,则具有较小整数转换等级类型的操作数将转换为具有更高等级的操作数的类型.

因此,如果正确理解它,在此代码块中:

int32_t x = INT32_MIN;
int y = 1;
x + y; // What happens here?
Run Code Online (Sandbox Code Playgroud)

在表达式中x + y,x必须被提升为int,并且INT32_MIN超出范围int.

这是标准中的错误还是我遗漏了什么?

换句话说,x + y根据标准的定义,此上下文中的表达式评估了什么?

c type-conversion integer-promotion language-lawyer

8
推荐指数
1
解决办法
1560
查看次数

gcc 7.2:警告:左移计数> =类型的宽度

即使我投出了每一个正确的操作数unsigned long long,警告仍然存在.不应该uint8_t << uint64_t有这样的隐式演员:(uint64_t) uint8_t << uint64_t

这个答案表明我可以提升任何一个操作数,并且整个表达式都会被强制转换unsigned long long,但这可能是错误的.

bool dgBioReadU64LE(DgBioFile *file, uint64_t *x) {
    uint8_t u[8];
    if (!dgBioReadU8v(file, LEN(u), u)) return false;
    *x = u[0]|(u[1]<<8ULL)|(u[2]<<16ULL)|(u[3]<<24ULL)|(u[4]<<32ULL)|(u[5]<<40ULL)|(u[6]<<48ULL)|(u[7]<<56ULL);
    return true;
}

bool dgBioReadU64BE(DgBioFile *file, uint64_t *x) {
    uint8_t u[8];
    if (!dgBioReadU8v(file, LEN(u), u)) return false;
    *x = u[7]|(u[6]<<8ULL)|(u[5]<<16ULL)|(u[4]<<24ULL)|(u[3]<<32ULL)|(u[2]<<40ULL)|(u[1]<<48ULL)|(u[0]<<56ULL);
    return true;
}
Run Code Online (Sandbox Code Playgroud)

c gcc

0
推荐指数
1
解决办法
714
查看次数