显式转换是否始终与隐式转换相同?

时间:2013-10-28 15:42:36

标签: c visual-studio warnings

在Visual C中我有:

#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
typedef int HFILE;
HFILE stat_fh = INVALID_HANDLE_VALUE;

我有警告:

"..warning C4047: '=' : 'HFILE' differs in levels of indirection from 'HANDLE'"

如果通过将 INVALID_HANDLE_VALUE 强制转换为 HFILE 类型来删除警告,是否可以? 我假设编译器已经自动执行完全相同的操作。

2 个答案:

答案 0 :(得分:1)

它可能会发生工作,但它并不好(虽然它似乎是微软所期望的;见下文)。

首先,你的术语有点偏。 强制转换是一个运算符,由括号中的类型名称组成。它指定了显式转换。没有隐式演员或“自动演员”这样的东西。你所谓的“强迫演员”只是一个演员;你称之为“自动演员”的是隐式转换

HFILE只是int的另一个名称。根据{{​​3}},HANDLEvoid*的typedef(别名)。该语言未定义从任何指针类型到int的隐式转换。在这种情况下,您的编译器会让您逃脱并发出警告。实际上,分配是约束违规,需要诊断消息。你的编译器可以(并且恕我直言)应该使用致命的错误消息拒绝你的程序。

如果您有指针值,则应将其指定给相同类型的指针变量

如果您要为HANDLE分配stat_fh值,则应将stat_fh声明为HANDLE,而不是int(甚至是HFILE作为int,正如我所说的仅仅是HFILE}的另一个名称。

为什么要将int定义为HFILE的别名?

更新:

我发现typedef int HFILE; 实际上是由Microsoft 定义的

HFILE

他们的文档还说OpenFile是“由Microsoft's documentation打开的文件的句柄,而不是OpenFile”。如果您按照这些链接进行操作,则会看到不建议使用OpenFile

另一方面,OpenFile的文档说明HFILE打开的文件(返回int,即HANDLE)应该被关闭将句柄传递给CreateFile,其中void*(即OpenFile)参数。

这是令人震惊的,我猜这是微软决定不鼓励使用HFILE的部分原因。

据我所知(虽然我不是Windows程序员,所以我可能会遗漏某些内容),但没有充分理由使用{{1}}。

答案 1 :(得分:1)

是的,当两种类型的转换(“强制转换”)都适用时 - 显式和隐式 - 显式转换的语义与隐式转换的语义完全相同。

请注意,在您的情况下,隐式转换不适用。在WinodwsAPI中,HANDLE通常被定义为指针类型。您正尝试将其转换为int类型。标准C不允许从指针类型隐式转换为int。这意味着以下声明

HFILE stat_fh = INVALID_HANDLE_VALUE;

包含约束违规。即它应该是不可编译的。所以,你的问题实际上没有实际意义(假设将HANDLE转换为int确实是你想做的事情。在这种情况下,显式转换是 only 选项。

如果您的编译器可以隐式地执行此转换(仅仅是警告),那么它只是编译器的一个怪癖,根本与标准C语言无关。