将变量强制转换为 (void *) 有什么效果?
在 C 程序中,我看到以下语句:
memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
(void*) case 的作用是什么?这是为 Microchip C30 编译器编写的。
AppConfig 的定义如下:
APP_CONFIG AppConfig; // APP_CONFIG is obviously a structure...
SerializedMACAddress 的定义如下:
static ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6};
编辑:我应该在之前声明这一点,但 memcpypgm2ram 定义为: #define memcpypgm2ram(a,b,c) memcpy(a,b,c)
所以基本上,void *memcpy(void *dest, const void *src, size_t n);
In a C program I see the following statement:
memcpypgm2ram((void*)&AppConfig.MyMACAddr, (ROM void*)SerializedMACAddress, sizeof(AppConfig.MyMACAddr));
What does the (void*) case do? This is written for the Microchip C30 compiler.
AppConfig is defined like this:
APP_CONFIG AppConfig; // APP_CONFIG is obviously a structure...
SerializedMACAddress is defined like this:
static ROM BYTE SerializedMACAddress[6] = {MY_DEFAULT_MAC_BYTE1, MY_DEFAULT_MAC_BYTE2, MY_DEFAULT_MAC_BYTE3, MY_DEFAULT_MAC_BYTE4, MY_DEFAULT_MAC_BYTE5, MY_DEFAULT_MAC_BYTE6};
EDIT: I should have stated this before but memcpypgm2ram is defined as:
#define memcpypgm2ram(a,b,c) memcpy(a,b,c)
so basically, void *memcpy(void *dest, const void *src, size_t n);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
void* 是通用数据指针类型,当用作参数类型时,表示函数在“裸”内存块上工作。它不能被取消引用。
任何其他数据指针类型都可以隐式转换为
void*
,因此显式转换可能是错误的(不必要),或者是损坏编译器的解决方法,或者是转换为unsigned 的简写char *
(在这种情况下,这是接口损坏的解决方法)。void*
is the universal data pointer type, that, when used as an argument type, denotes that a function works on "bare" memory blocks. It cannot be dereferenced.Any other data pointer type can be implicitly converted to
void*
, so the explicit cast is probably either wrong (unnecessary), or a workaround for a broken compiler, or a shorthand to cast tounsigned char *
(in which case it's a workaround for a broken interface).强制转换
void *
将某种类型的指针转换为通用指针。The cast
void *
converts a pointer of some type into a Generic Pointer.memcpypgm2ram 函数不需要特定类型。它应该用以下原型定义: memcpypgm2ram(void* p1, void* p2, int n);
“void *”是对通用指针类型的强制转换。
该函数仅接受任意类型的两个指针,并将 n 个字节(在您的情况下为 n=sizeof(AppConfig.MyMACAddr))从一个地址复制到另一个地址。
The memcpypgm2ram function does not need a specific type. It should be defined with the following prototype : memcpypgm2ram(void* p1, void* p2, int n);
"void *" is a cast to a generic pointer type.
The function just takes two pointers of any type and copy n bytes (in your case n=sizeof(AppConfig.MyMACAddr)) from one address to the other.
memcpypgm2ram 可能采用 void 指针作为参数。 C 的类型足够强,可以识别 &AppConfig.MyMACAddr 的类型是 (MACAddr*),并且如果您不将其转换为 void*,则会发出编译时错误。
关键是 memcpypgm2ram 是一个可以处理内存中保存的任何字节的函数,因此它不接受强类型指针作为参数。
memcpypgm2ram presumably takes a void pointer as it's argument. C is strongly enough typed to recognize that the type of &AppConfig.MyMACAddr is (MACAddr*) and will emit a compile-time error if you don't cast it as a void*.
The point is that memcpypgm2ram is a function that works on any bytes held in memory, so it won't accept strongly typed pointers as arguments.
在这种情况下,可以使用强制转换为 (void *) 来消除编译器的警告。
in this case, casting to (void *) may be used to get rid of compiler's warning.
在没有看到更多上下文的情况下,无法说明在这种特定情况下使用
(void *)
转换的意义是什么(memcpypgm2ram
是如何声明的?)。在 C 语言(以及 C++)中,指针类型可以隐式转换为
void *
类型,这意味着在指针转换中通常没有理由使用显式强制转换为void * 类型。在您的示例中,所有转换看起来都是指针转换,因此,考虑到我所说的,不需要显式转换为
void *
。另一种可能性是原始指针类型是 const 限定的,因此使用强制转换为
void *
来删除 const 限定。但是,我在您提供的内容中没有看到任何 const 限定,这再次意味着很可能不需要强制转换为void *
。我的猜测是,无论是谁把它放在那里,都是“以防万一”,没有任何真正的原因。简而言之,
(void *)
转换将指针转换为void *
类型。但由于该转换无论如何都会隐式发生,因此完全没有必要进行强制转换(假设使用 void * 参数声明 memcpypgm2ram)。There's no way to say what was the point of using
(void *)
cast in this specific case without seeing more context (how ismemcpypgm2ram
declared?).In C language (as well as in C++) pointer types are implicitly convertible to
void *
type, which means that in pointer conversions there's usually no reason to use an explicit cast tovoid *
type. It looks like in your example all conversions are pointer conversions, so, taking into account what I said, the explicit cast tovoid *
is not required.Another possibility though is that the original pointer types are const-qualified, so the cast to
void *
was used to remove the const-qualification. However, I don't see any const-qualifications in what you provided, which means, again, that most likely that cast tovoid *
is unnecessary. My guess would be that whoever put it there did it "just in case" for no real reason.In short, the
(void *)
cast converts the pointers tovoid *
type. But since that conversion would happen implicitly anyway, the cast is totally unnecessary (assumingmemcpypgm2ram
is declared withvoid *
parameters).