C 什么时候真正需要显式强制转换?

C 什么时候真正需要显式强制转换?,c,casting,C,Casting,以这段代码为例: const char *s; char *t = s; 这将发出以下警告:警告:分配从指针目标类型丢弃“const”限定符 只需添加一个强制转换,就可以很容易地使编译器静音: char *t = (char*)s; 您可以对正则变量做类似的事情,而不仅仅是指针,而且它不仅适用于常量限定符。您基本上可以从任何类型强制转换为任何类型,即使其中一些强制转换会造成麻烦 我还读到,您永远不应该强制转换malloc,因为向void指针进行强制转换和从void指针进行强制转换总是安全的

以这段代码为例:

const char *s;
char *t = s;
这将发出以下警告:
警告:分配从指针目标类型丢弃“const”限定符

只需添加一个强制转换,就可以很容易地使编译器静音:

char *t = (char*)s;
您可以对正则变量做类似的事情,而不仅仅是指针,而且它不仅适用于常量限定符。您基本上可以从任何类型强制转换为任何类型,即使其中一些强制转换会造成麻烦

我还读到,您永远不应该强制转换
malloc
,因为向void指针进行强制转换和从void指针进行强制转换总是安全的

但是演员们实际上做什么呢?除了防止编译器发出警告之外,它还做了其他事情吗。什么时候确实需要显式强制转换

澄清:


我说的是作业。不是像
double res=(double)a/b
这样的东西。在这种情况下,我知道强制转换的作用,在这种情况下,我们可以很容易地摆脱显式强制转换,转而使用隐式强制转换,如下所示:
double c=a;双res=c/b
或just
double res=(1.0*a)/b

C 2018 6.5.16.1 1 1指定了简单赋值运算符的约束。对于既是指向
void
指针以外的指针的左操作数和右操作数,它们表示:

下列条件之一应适用:…两个操作数都是指向兼容类型的合格或不合格版本的指针,左侧指向的类型具有右侧指向的类型的所有限定符

因此,C标准要求指针具有相同的“种类”(兼容类型),并且赋值不删除任何限定符(左侧包含右侧的所有限定符,但可能更多)。如果违反此要求,编译器必须发出诊断消息(尽管它仍然可以选择接受程序;该消息可以是警告而不是错误)

6.5.4在第2至4段中规定了铸件的约束条件。它们都不限制从一种指针类型到另一种指针类型的转换。因此,您可以使用强制转换指定任何指针转换,并且编译器无需发出诊断(尽管有些编译器可能选择发出诊断)

其基本原理是,赋值允许隐式地进行指针“正常”使用的转换,但显式地使用强制转换允许指针的“特殊”使用

允许使用cast进行特定转换的事实并不一定意味着它有意义或定义良好。6.3.2.3定义了指针转换的一些规则。例如,
int*
可以转换为
char*
,结果指针可用于检查表示
int
的字节。但是将
char*
转换为
int*
可能会导致未定义的行为。因此,强制转换将允许您进行转换,但结果是否有用或是您想要的取决于C标准中的其他规则


当允许并定义转换时,无论它是通过赋值隐式发生还是通过强制转换显式发生,都具有相同的效果。演员阵容不会改变转换的内容;它只会更改是否允许(无诊断)。

我不确定是否存在不能使用变量的情况,但它通常会降低表达式(如
(double)a/b
)的可读性,以避免整数除法。这就是你要问的吗?@Ry-我会澄清的。还有一秒钟,这些警告似乎是关于标准不合格代码的,并且被允许是错误的:底线是cast通过告诉编译器
s
是type
char*
而不是
const char*
来掩盖警告,因此它允许在没有警告的情况下分配到
t
,但是--(而且总是有一个but…)现在
t
指向
s
,但是…
t
是可变的,任何接收
t
的函数都可以有效地假设它指向可变的内存,但事实并非如此,如果有人试图修改内存
t
指向(而且它恰好是字符串文本,等等)--BAM SEGFAULT。本质上,强制转换使编译器对
t
的类型成为谎言。这是一个有趣的问题。有些强制转换实际上会更改编译器生成的代码,如
(双精度)a/b
多样性,还有一些只允许编译器接受它会抱怨的代码。我不确定“需要显式强制转换的位置”问题是否有一句话的答案。