当前位置: 首页 > 知识库问答 >
问题:

C整数隐式转换

潘鸿文
2023-03-14

我试图理解以下转换的机制

#include <stdio.h>
#include <stdint.h>

int main() {
    
    int a = 0xffffffff;  
    printf("%d", a); // prints -1
    return 0;
}

根据整数常量,0xffffffff的类型是无符号int。这可以通过执行printf(“%s”,0xffffffff)轻松检查;

根据内隐转换语义学:

“整数提升是对秩小于或等于int[…]秩的任何整数类型的值的隐式转换设置为int或unsigned int类型的值。“

如下文所述

msgstr"所有有符号整数类型的行列等于相应无符号整数类型的行列"

因此,升级适用,因为无符号int的秩与int的秩相同。

这种晋升被定义为

如果int可以表示原始类型的整个值范围(或原始位字段的值范围),则该值将转换为int类型。否则,该值将转换为无符号int

但是,这就是我不理解的,int不能代表无符号int4294967295,但它仍然被转换为int。这种情况在没有任何狭窄警告的情况下发生。为什么会这样?

共有2个答案

董永宁
2023-03-14

问题是,您正在将一个无符号数(值0xffffffff)转换为一个有符号int,该值超出了它的有效值范围(您正试图将4294967296转换为int,但int仅涵盖-21474836482147483647)因此您会得到未定义的行为。

根据您使用的编译器(以及体系结构),您可以获得不同的值,甚至由于溢出而出现异常。我的猜测是,编译器使用了2的补码,它只是将该数字重新解释为其等效的二进制表示形式,即-1-1在内部表示为四个字节0xff)。

南门飞
2023-03-14

由于常量0xffffff(假设int为32位)的类型为无符号int,用于初始化类型为int对象,这涉及从无符号int无符号int的转换。

C标准第6.3.1.3节描述了整数类型之间的转换:

1当整数类型的值转换为除\u Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变。

2否则,如果新类型是无符号的,则通过在新类型中可以表示的最大值之外重复添加或减去一个值来转换该值,直到该值处于新类型的范围内。

3否则,新类型已签名,且无法在其中表示值;要么结果是实现定义的,要么引发实现定义的信号

第3款适用于本案。所讨论的值位于目标类型的范围之外,并且目标已被签名。因此会发生实现定义的转换。

如果你使用-W转换标志使用gcc编译,它会给你一个警告:

x1.c:6:5: warning: conversion of unsigned constant value to negative integer [-Wsign-conversion]
     int a = 0xffffffff;  

也:

这可以通过执行printf("%s",0xffffff);来轻松检查

这会调用未定义的行为,因为%s格式说明符需要一个指向以null结尾的字符串char*。您传递的值不是这种类型,可能不是有效的内存地址。

整数提升在这里也不适用,因为没有比intunsigned int级别更低的表达式。

 类似资料:
  • 问题内容: 我正在做s和s的乘法和除法,但我忘记了隐式转换规则(问题中的单词似乎太含糊,以至于Google不能比在这里问得更快)。 如果我有两个s,但我想进行浮点除法,是否只需要强制转换一个或两个操作数?如何相乘-如果我将a 和an 相乘,答案是a 吗? 问题答案: 您不能将结果除以a ,反之亦然。 因此答案是: 如果我有两个s,但是我想做浮点除法…? 一个演员就足够了。 如果我将a 和an 相乘

  • 一、隐式转换 1.1 使用隐式转换 隐式转换指的是以 implicit 关键字声明带有单个参数的转换函数,它将值从一种类型转换为另一种类型,以便使用之前类型所没有的功能。示例如下: // 普通人 class Person(val name: String) // 雷神 class Thor(val name: String) { // 正常情况下只有雷神才能举起雷神之锤 def hamm

  • 我正在接收 无符号到整数的隐式转换 使用以下代码: 但是当我将方法的 路由到< code > Admin::questions controller 的< code>create方法,为什么它不起作用?我是rails和命名空间的新手,所以我可能忽略了一些显而易见的东西。 编辑: 问题控制器的命名空间在admin下。

  • 我正在尝试将文件导入Excel,但是当我尝试使用相关数据创建记录时,它会向我显示以下错误: 在此行中: 这是我用来导入的列表控制器和方法: 我的方法导入到列表控制器中: 这是我的“deta”控制器:

  • JavaScript 是非常宽容的,「来者不拒」,不在乎什么类型。 例如,它如果想要接受数字,它并不拒绝其他类型的值,而是试图把它们转换成数字: > '5' - '2' 3 > '5' * '2' 10 自动转换为布尔值通常不会引起问题,而且往往很有用(译注:比如在C语言里,根本就没有布尔类型。 即使如此,这些隐式转换也会引起怪癖(quirks)。 但是当自动转换为字符串时,可能会引起问题。 一

  • 我在尝试更改哈希值时遇到了一个奇怪的问题。我有以下设置: 当我执行此代码时,我得到:“TypeError:没有将符号隐式转换为整数”,尽管 item[:company_name] 的输出是预期的字符串。我做错了什么?