在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 类型来删除警告,是否可以? 我假设编译器已经自动执行完全相同的操作。
答案 0 :(得分:1)
它可能会发生工作,但它并不好(虽然它似乎是微软所期望的;见下文)。
首先,你的术语有点偏。 强制转换是一个运算符,由括号中的类型名称组成。它指定了显式转换。没有隐式演员或“自动演员”这样的东西。你所谓的“强迫演员”只是一个演员;你称之为“自动演员”的是隐式转换。
HFILE
只是int
的另一个名称。根据{{3}},HANDLE
是void*
的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语言无关。