简体   繁体   English

为什么我可以对static * cast使用void *但不能对char *使用

[英]Why can I use static_cast With void* but not With char*

I know that reinterpret_cast is primarily used going to or from a char* . 我知道reinterpret_cast主要用于从char*访问或从char*

But I was surprised to find that static_cast could do the same with a void* . 但是我很惊讶地发现static_cast可以对void*进行同样的处理。 For example: 例如:

auto foo "hello world"s;
auto temp = static_cast<void*>(&foo);
auto bar = static_cast<string*>(temp);

What do we gain from using reinterpret_cast and char* over static_cast and void* ? 通过在static_castvoid*使用reinterpret_castchar* ,我们可以得到什么? Is it something to do with the strict aliasing problem? 与严格的别名问题有关吗?

Generally speaking, static_cast will do cast any two types if one of them can be cast to the other implicitly . 一般而言,如果可以将static_cast任意一种类型隐式转换为另一种类型,则static_cast可以转换任何两种类型。 That includes arithmetic casts, down-casts, up-casts and cast to and from void* . 包括算术转换,向下转换,向上转换以及与void*

That is, if this cast is valid: 也就是说,如果此强制转换有效:

void foo(A a);
B b;
foo(b);

Then the both static_cast<B>(a) and static_cast<A>(b) will also be valid. 然后static_cast<B>(a)static_cast<A>(b)都将有效。

Since any pointer can be cast implicitly to void* , thus your peculiar behavior. 由于任何指针都可以隐式转换为void* ,因此您的行为很特殊。

reinterpret_cast do cast by reinterpreting the bit-pattern of the values. reinterpret_cast通过重新解释值的位模式来进行强制转换。 That, as you said in the question, is usually done to convert between unrelated pointer types. 正如您在问题中所说的那样,通常是在不相关的指针类型之间进行转换。

Yes, you can convert between unrelated pointer types through void* , by using two static_cast : 是的,您可以使用两个static_cast通过void*在不相关的指针类型之间进行转换:

B *b;
A *a1 = static_cast<A*>(b); //compiler error
A *a2 = static_cast<A*>(static_cast<void*>(b)); //it works (evil laugh)!

But that is bending the rules. 但是,这违反了规则。 Just use reinterpret_cast if you really need this. 如果确实需要,请使用reinterpret_cast

Your question really has 2 parts: 您的问题确实包含两个部分:

  1. Should I use static_cast or reinterpret_cast to work with a pointer to the underlying bit pattern of an object without concern for the object type? 我是否应该使用static_castreinterpret_cast与指向对象的基础位模式的指针一起工作而不必担心对象类型?
  2. If I should use reinterpret_cast is a void* or a char* preferable to address this underlying bit pattern? 如果我应该使用reinterpret_cast是更适合解决此基础位模式的void*char*

static_cast : Converts between types using a combination of implicit and user-defined conversions static_cast :使用隐式和用户定义的转换的组合在类型之间进行转换

In 5.2.9[expr.static.cast]13 the standard, in fact, gives the example: 实际上,在5.2.9 [expr.static.cast] 13中,该标准给出了示例:

T* p1 = new T;
const T* p2 = static_cast<const T*>(static_cast<void*>(p1));

It leverages the implicit cast: 它利用隐式强制转换:

A prvalue pointer to any (optionally cv-qualified) object type T can be converted to a prvalue pointer to (identically cv-qualified) void . 可以将指向任何(可选为cv限定)对象类型T的prvalue指针转换为指向(相同为cv限定) void的prvalue指针。 The resulting pointer represents the same location in memory as the original pointer value. 生成的指针与原始指针值在内存中的位置相同。 If the original pointer is a null pointer value, the result is a null pointer value of the destination type. 如果原始指针是空指针值,则结果是目标类型的空指针值。 * *

There is however no implicit cast from a pointer of type T to a char* . 但是,没有从类型T的指针到char*隐式转换。 So the only way to accomplish that cast is with a reinterpret_cast . 因此,完成该转换的唯一方法是使用reinterpret_cast

reinterpret_cast : Converts between types by reinterpreting the underlying bit pattern reinterpret_cast :通过重新解释基础位模式在类型之间转换

So in answer to part 1 of your question when you cast to a void* or a char* you are looking to work with the underlying bit pattern, reinterpret_cast should be used because it's use denotes to the reader a conversion to/from the underlying bit pattern. 因此,当您要转换为void*char*您想使用基础位模式来回答问题的第1部分,因此应使用reinterpret_cast因为它的用途是向读者表示向/从基础位的转换图案。

Next let's compare void* to char* . 接下来让我们比较void*char* The decision between these two may be a bit more application dependent. 两者之间的决定可能取决于应用程序。 If you are going to use a standard library function with your underlying bit pattern just use the type that function accepts: 如果要将标准库函数与基础位模式一起使用,请使用该函数接受的类型:

  • void* is used in the mem functions provided in the cstring library void*cstring库提供的mem函数中使用
  • read and write use char* as inputs readwrite使用char*作为输入

It's notable that C++ specific libraries prefer char* for pointing to memory. 值得注意的是,C ++特定的库更喜欢char*来指向内存。 Holding onto memory as a void* seems to have been preserved for compatibility reasons as pointer out here . 出于兼容性原因,保留内存为void*似乎已保留为此处的指针。 So if a cstring library function won't be used on your underlying bit patern, use the C++ specific libraries behavior to answer part 2 of your question: Prefer char* to void* . 因此,如果在基础位模式上不使用cstring库函数,请使用C ++特定的库行为来回答问题的第2部分:将char*首选为void*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我不能static_cast一个包含void *的元组到一个包含char *的元组? - Why can't I static_cast a tuple containing a void* to one containing a char*? 为什么我可以static_cast void *到int *但不能到int *&? - Why can I static_cast void* to int* but not to int*&? 为什么我不能 static_cast char* 到 std::byte*? - Why I can't static_cast char* to std::byte*? reinterpret_cast的 <int*> (char *)与static_cast <int*> (的static_cast <void*> (char *)) - 使用哪个? - reinterpret_cast<int*>(char*) vs. static_cast<int*>(static_cast<void*>(char*)) — which to use? 我应该使用它还是static_cast <void*> 然后是static_cast <myType*> 避免重新解释? - should I use it or static_cast<void*> then static_cast<myType*> to avoid reinterpret_cast? 为什么我不能使用static_cast <const char**> (str)而不是(const char **)str? - Why cant i use static_cast<const char**>(str) instead of (const char**)str? 为什么不能static_cast一个双void指针? - Why can't static_cast a double void pointer? static_cast void * char * vs static_cast void ** char ** - static_cast void* char* vs static_cast void** char** 为什么我不能在char *和unsigned char *之间进行static_cast? - Why can't I static_cast between char * and unsigned char *? 为什么我不能将 void* static_cast 转换为函数指针? - Why can't I static_cast a void* to a pointer-to-function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM