Namespaces
Variants

cast operator

From cppreference.net

执行显式类型转换

目录

语法

( 类型名称 ) 表达式

其中

类型名 - 可以是 void 类型或任意 标量类型
表达式 - 任意 表达式 ,其类型为 标量类型 (除非 类型名 void ,此时表达式可为任意类型)

说明

如果 type-name void ,那么 expression 将仅为其副作用而被求值,其返回值将被丢弃,这与 expression 单独作为 表达式语句 使用时的情况相同。

否则,如果 类型名 表达式 的类型完全一致,则不执行任何操作(除非 表达式 具有浮点类型,且其表示的范围和精度超过其类型所指示的范围——详见下文)。

否则, expression 的值将按照以下方式转换为 type-name 所指定的类型:

每个 如同通过赋值进行的隐式转换 都是允许的。

除了隐式转换之外,还允许以下转换:

  • 任何整数都可以强制转换为任何指针类型。除了空指针常量(如 NULL ,其 无需强制转换 ),结果是实现定义的,可能未正确对齐,可能不指向引用类型的对象,且可能是 陷阱表示
  • 任何指针类型都可以强制转换为任何整数类型。结果是实现定义的,即使是空指针值(它们不必然产生零值)。若结果无法在目标类型中表示,则行为未定义(无符号整数在指针转换时不实现模运算)。
  • 任何对象指针都可以强制转换为任何其他对象指针。若该值未按目标类型正确对齐,则行为未定义。否则,若将值转换回原始类型,则与原始值比较相等。若将对象指针强制转换为任何字符类型指针,结果指向对象的最低字节,并可递增至目标类型的 sizeof 值(换言之,可用于检查 对象表示 或通过 memcpy memmove 创建副本)。
  • 任何函数指针都可以强制转换为任何其他函数类型的指针。若将结果指针转换回原始类型,则与原始值比较相等。若使用转换后的指针进行函数调用,则行为未定义(除非函数类型是 兼容的 )。
  • 在指针(对象指针或函数指针)之间转换时,若原始值是其类型的空指针值,则结果是目标类型的正确空指针值。

在任何情况下(无论是执行隐式转换还是同类型转换),如果 expression type-name 是浮点类型,且 expression 的表示范围和精度高于其类型所指示的范围(参见 FLT_EVAL_METHOD ),则会去除超出目标类型范围与精度的部分以匹配目标类型。

强制转换表达式的 值类别 始终为非左值。

注释

由于 const volatile restrict _Atomic 限定符仅对 左值 产生影响,强制转换为 cvr 限定或原子类型完全等同于转换为对应的非限定类型。

将结果强制转换为 void 有时可用于消除编译器关于未使用结果的警告。

此处未列出的转换是不允许的。具体来说,

  • 指针与浮点类型之间不存在转换;
  • 函数指针与对象指针(包括 void * )之间不存在转换。

若实现提供 intptr_t 和/或 uintptr_t ,则从对象类型指针(包括 cv void )到这些类型的转换始终是良定义的。但函数指针不能保证这一点。

(since C99)

请注意,函数指针与对象指针之间的转换被许多编译器作为扩展功能接受,并且某些 POSIX dlsym 函数的使用场景也预期这种转换。

示例

#include <stdio.h>
int main(void)
{
    // 检查对象表示是强制转换的合法用途
    const double d = 3.14;
    printf("The double %.2f (%a) is: ", d, d);
    for (size_t n = 0; n != sizeof d; ++n)
        printf("%02X ", ((unsigned char*)&d)[n]);
    // 边界情况
    struct S { int x; } s;
    // (struct S)s; // 错误:非标量类型,即使
                    // 转换为相同类型不执行任何操作
    (void)s; // 允许将任何类型转换为 void
}

输出:

The double 3.14 (0x1.91eb851eb851fp+1) is: 1F 85 EB 51 B8 1E 09 40

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • 6.5.5 强制类型转换运算符 (p: 83-84)
  • C17 标准 (ISO/IEC 9899:2018):
  • 6.5.4 强制类型转换运算符 (p: 65-66)
  • C11 标准 (ISO/IEC 9899:2011):
  • 6.5.4 强制类型转换运算符 (p: 91)
  • C99标准(ISO/IEC 9899:1999):
  • 6.5.4 强制类型转换运算符(第81页)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.3.4 强制转换运算符

参见

C++ 文档 关于 显式类型转换