一种C ++运算符,它通过重新解释基础位模式简单地允许类型之间的转换。在一般使用中,这相当于指向要转换为任何其他指针类型的指针,并且它还可以允许将整数类型转换为任何指针类型,反之亦然。
给出以下包装(简化): 模板 类包装器 { 公共:自动 val() { 返回 t; } 私人:T t; }; 我正在尝试获取一系列包装纸来
是否将“指向结构体的指针的地址”转换为“第一个成员是指向结构体的指针的结构体的地址”UB?
我有一个名为 Node 的结构,其第一个成员是 Node* p_next 我有一个指向第一个节点的指针,名为 p_head 我想将 Node** 类型的 &p_head 转换为 Node*,并将其存储在
考虑以下代码(以及 VirtualAlloc() 返回 void* 的事实): 字节* pbNext = reinterpret_cast( VirtualAlloc(NULL, cbAlloc, MEM_COMMIT, PAGE_READWRITE)); 为什么是
我有两个具有相同内存布局的struct struct Temp和struct MyTemp,我想将struct Temp类型的返回值强制转换为struct MyTemp类型,例如在C++中,我可以实现这个go...
reinterpret_cast从char*到uint32_t*在CPP中是未定义的行为吗?
我从事一个中型开源项目,该项目需要将原始字节解释为不同类型。这是通过创造性地使用重新解释铸造来实现的。然而,在一个简单的测试用例中,comp...
reinterpret_cast 可以用来将指针强制转换为未实现的类指针吗?
我有两个类,一个有实现,另一个没有。然后在 main() 函数中,我定义了一个带有实现的类实例,然后reinterpret_cast
我试图在由 void 指针指向的任意内存块中创建对结构的引用。 但我似乎无法解决这个问题! 鉴于下面的示例代码(在最新的 clang 上测试),我...
为什么C++分配器使用reinterpret_cast以及如何避免它?
我试图实现自己的小型分配器用于测试目的,在设计它时我认为我不知道如何在不违反严格别名规则的情况下实现它。 在大多数[开放所以...
我最近在reinterpret_cast上读了很多书,因为我想确保我正确使用它并且不会意外地调用未定义的行为。我觉得 cppreference 和这篇关于
我写了一段代码,积累了不必要的内存空间,并在需要时将其归还,将其组织为堆栈(客户的要求很奇怪)。 void* 堆栈 = nullptr; 模板 我写了一段代码,积累了不必要的内存空间,并在需要时将其归还,将其组织为堆栈(客户的要求很奇怪)。 void* stack = nullptr; template <typename P> void push(P* p) { // reinterpret memory space of *p as a storage for the address of the top element of the stack; *reinterpret_cast<void**>(p) = stack; // now *p is the top element, so update stack to point to *p; stack = p; } template <typename P> P* pop() { if (stack == nullptr) throw; // get the address of the top element P* p = static_cast<P*>(stack); // now stack should point to the next element after *p, which address is stored in *p's memory space stack = *reinterpret_cast<void**>(stack); return p; } stack是指向顶部元素的指针。当新的内存空间为 pushed 时,其前 8 个字节用于存储前一个元素的地址,stack 被更新。一个简单的栈链。 问题 当我试图实现这种行为时,编译器经常这样说(我知道某些内存操作是非法的): 对强制转换的赋值是非法的,不支持左值强制转换 我想知道我的实施现在是否合法? 示例 #include <iostream> #include <bitset> constexpr size_t bytes_8 = 8 * 8; constexpr size_t bytes_20 = 8 * 20; constexpr size_t bytes_50 = 8 * 50; // we assume that std::bitset holds its data contigiously in the beginning struct A { std::bitset<bytes_8> bits; }; struct B { std::bitset<bytes_20> bits; }; struct C { std::bitset<bytes_50> bits; }; int main() { // Imagine they were allocated on heap: A a; B b; C c; std::cout << "Addresses" << '\n' << "a: " << &a << "\t" << "b: " << &b << "\t" << "c: " << &c << std::endl << std::endl << std::endl; push<A>(&a); std::cout << "---------- push<A>(&a) ----------\n" << "'a' is the top element (and the only one), so 'stack' points to it,\n" << "meanwhile 'a' stores the address of the previous element (none)\n\n" << "stack: " << stack << "\ta.bits: " << std::hex << a.bits.to_ullong() << std::endl << std::endl; push<B>(&b); std::cout << "---------- push<B>(&b) ----------\n" << "now 'b' is the top element, so 'stack' updates to point to it,\n" << "'b' stores the address of the previous element (a)\n\n" << "stack: " << stack << "\tb.bits: " << std::hex << b.bits.to_ullong() << std::endl << std::endl; push<C>(&c); std::cout << "---------- push<C>(&c) ----------\n" << "finally 'c' is the top element and 'stack' points to it,\n" << "'c' stores the address of the previous element (b)\n\n" << "stack: " << stack << "\tc.bits: " << std::hex << c.bits.to_ullong() << std::endl << std::endl << std::endl; auto p1 = pop<C>(); std::cout << "---------- pop<C>() ----------\n" << "'b' is the top element and the next one after it is 'a'\n\n" << "ret: " << p1 << "\nstack: " << stack << "\tb.bits: " << std::hex << b.bits.to_ullong() << std::endl << std::endl; auto p2 = pop<B>(); std::cout << "---------- pop<B>() ----------\n" << "'a' is the top element and the last one in the stack\n\n" << "ret: " << p2 << "\nstack: " << stack << "\ta.bits: " << std::hex << a.bits.to_ullong() << std::endl << std::endl; auto p3 = pop<A>(); std::cout << "---------- pop<A>() ----------\n" << "the stack is empty\n\n" << "ret: " << p3 << "\nstack: " << "0x" << stack << std::endl << std::endl; return 0; } 输出: Addresses a: 0x7fffffffdc20 b: 0x7fffffffdc40 c: 0x7fffffffdc60 ---------- push<A>(&a) ---------- 'a' is the top element (and the only one), so 'stack' points to it, meanwhile 'a' stores the address of the previous element (none) stack: 0x7fffffffdc20 a.bits: 0 ---------- push<B>(&b) ---------- now 'b' is the top element, so 'stack' updates to point to it, 'b' stores the address of the previous element (a) stack: 0x7fffffffdc40 b.bits: 7fffffffdc20 ---------- push<C>(&c) ---------- finally 'c' is the top element and 'stack' points to it, 'c' stores the address of the previous element (b) stack: 0x7fffffffdc60 c.bits: 7fffffffdc40 ---------- pop<C>() ---------- 'b' is the top element and the next one after it is 'a' ret: 0x7fffffffdc60 stack: 0x7fffffffdc40 b.bits: 7fffffffdc20 ---------- pop<B>() ---------- 'a' is the top element and the last one in the stack ret: 0x7fffffffdc40 stack: 0x7fffffffdc20 a.bits: 0 ---------- pop<A>() ---------- the stack is empty ret: 0x7fffffffdc20 stack: 0x0 即使您设法删除未定义的行为,您的实现也不可能工作。 将元素推入堆栈会覆盖其中的一部分。这是一个有损操作。 sizeof void* 对象表示开头的 *p 字节已经消失,永远无法恢复。即使您不再使用该对象,它的析构函数仍然需要运行,并且通常需要该数据。
在 GCC 13.2 和 Clang 18.0.1 中使用 -O3,为操作符生成的程序集 < of a tuple of four std::uint16_t objects is less than impressive (pun intended). Two other implementations using
考虑以下代码: 结构块{ alignas(int) 无符号字符数据[sizeof(int)]; }; int main() { 块 buff[sizeof(double) / sizeof(int)]; ::new(&buff) 双(); 双 d = *std::
我有两个类,一个父类和一个子类(从父类继承)我想知道是否可以使用reinterpret_cast或som将子**转换/转换为父**。
在给定正确的静态断言的情况下,`reinterpret_cast` 是否会从派生 -> 内存 -> 基安全?
我正在编写 C++14 代码,需要尽快反序列化对象。 序列化位于内存中,并且与反序列化发生在同一进程中。 考虑一下: 结构体基础 { ...
我想知道C#中C++的reinterpret_cast相当于什么!? 这是我的样本: 类基类 { 受保护的 int 计数器 = 0; } Foo 类:基础 { 公共整数计数器 { 得到{ ret...
是否可以将分配的内存转换为对 c 数组的引用而不调用未定义的行为? 我在堆中有 4 个元素,希望将其视为 2x2 c 数组(传递给函数......
std::string Window::Exception::TranslateErrorCode(HRESULT hr) noexcept { char* pMsgBuf = nullptr; DWORD nMsgLen = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | 格式消息分配缓冲区
我正在尝试使用一些 C++ ARM 编译器来编译以下代码。 voidpairs_converter(const mem_t& mem, uint16_t* data) {/* 一些东西 */} 模板 排队 无效
我想实现一个返回默认值的通用函数,然后通过函数指针使用它来替换具有不同原型的其他函数。 例如: int 替换...
std::as_writable_bytes何时触发未定义的行为
我以为我终于理解了reinterpret_cast和严格别名,然后我遇到了这个例子,稍微修改了https://en.cppreference.co上的“无效标量”示例...