- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在 C++ 中,这段代码是否正确?
#include <cstdlib>
#include <cstring>
struct T // trivially copyable type
{
int x, y;
};
int main()
{
void *buf = std::malloc( sizeof(T) );
if ( !buf ) return 0;
T a{};
std::memcpy(buf, &a, sizeof a);
T *b = static_cast<T *>(buf);
b->x = b->y;
free(buf);
}
换句话说,*b
是一个生命周期开始的对象吗? (如果是这样,它到底是从什么时候开始的?)
最佳答案
这是未指定的,由N3751: Object Lifetime, Low-level Programming, andmemcpy支持其中说:
The C++ standards is currently silent on whether the use of memcpy to copy object representation bytes is conceptually an assignment or an object construction. The difference does matter for semantics-based program analysis and transformation tools, as well as optimizers, tracking object lifetime. This paper suggests that
uses of memcpy to copy the bytes of two distinct objects of two different trivial copyable tables (but otherwise of the same size) be allowed
such uses are recognized as initialization, or more generally as (conceptually) object construction.
Recognition as object construction will support binary IO, while still permitting lifetime-based analyses and optimizers.
我找不到任何讨论过这篇论文的 session 记录,所以它似乎仍然是一个悬而未决的问题。
C++14 草案标准目前在 1.8
[intro.object] 中说:
[...]An object is created by a definition (3.1), by a new-expression (5.3.4) or by the implementation (12.2) when needed.[...]
我们没有使用 malloc
并且标准中涵盖的用于复制普通可复制类型的情况似乎只引用 3.9
部分中已经存在的对象 < em>[基本类型]:
For any object (other than a base-class subobject) of trivially copyable type T, whether or not the object holds a valid value of type T, the underlying bytes (1.7) making up the object can be copied into an array of char or unsigned char.42 If the content of the array of char or unsigned char is copied back into the object, the object shall subsequently hold its original value[...]
和:
For any trivially copyable type T, if two pointers to T point to distinct T objects obj1 and obj2, where neither obj1 nor obj2 is a base-class subobject, if the underlying bytes (1.7) making up obj1 are copied into obj2,43 obj2 shall subsequently hold the same value as obj1.[...]
这基本上就是提案所说的内容,所以这不足为奇。
dyp 从 ub 邮件列表 中指出了关于这个主题的精彩讨论:[ub] Type punning to avoid copying .
提案 p0593 试图解决这个问题,但 AFAIK 尚未经过审查。
This paper proposes that objects of sufficiently trivial types be created on-demand as necessary within newly-allocated storage to give programs defined behavior.
它有一些本质上相似的激励示例,包括当前具有未定义行为的当前 std::vector 实现。
它提出了以下隐式创建对象的方式:
We propose that at minimum the following operations be specified as implicitly creating objects:
Creation of an array of char, unsigned char, or std::byte implicitly creates objects within that array.
A call to malloc, calloc, realloc, or any function named operator new or operator new[] implicitly creates objects in its returned storage.
std::allocator::allocate likewise implicitly creates objects in its returned storage; the allocator requirements should require other allocator implementations to do the same.
A call to memmove behaves as if it
copies the source storage to a temporary area
implicitly creates objects in the destination storage, and then
copies the temporary storage to the destination storage.
This permits memmove to preserve the types of trivially-copyable objects, or to be used to reinterpret a byte representation of one object as that of another object.
A call to memcpy behaves the same as a call to memmove except that it introduces an overlap restriction between the source and destination.
A class member access that nominates a union member triggers implicit object creation within the storage occupied by the union member. Note that this is not an entirely new rule: this permission already existed in [P0137R1] for cases where the member access is on the left side of an assignment, but is now generalized as part of this new framework. As explained below, this does not permit type punning through unions; rather, it merely permits the active union member to be changed by a class member access expression.
A new barrier operation (distinct from std::launder, which does not create objects) should be introduced to the standard library, with semantics equivalent to a memmove with the same source and destination storage. As a strawman, we suggest:
// Requires: [start, (char*)start + length) denotes a region of allocated
// storage that is a subset of the region of storage reachable through start.
// Effects: implicitly creates objects within the denoted region.
void std::bless(void *start, size_t length);In addition to the above, an implementation-defined set of non-stasndard memory allocation and mapping functions, such as mmap on POSIX systems and VirtualAlloc on Windows systems, should be specified as implicitly creating objects.
Note that a pointer reinterpret_cast is not considered sufficient to trigger implicit object creation.
关于c++ - "constructing"一个可以用 memcpy 简单复制的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30114397/
按照此页面上的教程:https://cdkworkshop.com/20-typescript/40-hit-counter/300-resources.html 我相信this ,传递给 Table
据我所知std::allocator::construct在旧版本的 C++ 上仅需要两个参数;第一个是指向原始的、未构造的内存的指针,我们要在其中构造 T 类型的对象。第二个是用于初始化该对象的元素
我正在阅读 CanJS API 文档并遇到 can.Construct.extend http://canjs.com/docs/can.Construct.extend.html .我知道 can.
考虑 struct C { C() { printf("C::C()\n" ); } C(int) { printf("C::C(i
阅读 git repo 中截取的以下代码时遇到一些问题。链接到存储库和问题: https://github.com/paolo-sz/fatty/blob/master/src/winmain.c#L
除了将一种高级语言转换为另一种高级语言的编译器之外,任何编译为机器代码的编译器都需要用汇编编写吗? 最佳答案 编译器的源代码不需要用汇编语言编写。例如,CPython 编译器(好吧,技术上解释器)的(
我正在努力计算 worklist算法,我不想实现迭代算法,因为它需要很多冗余步骤。 我用来计算实时变量工作列表的算法如下 任何人都可以为下面给出的示例向我解释一下,初始工作列表是什么以及工作列表算法将
我有这部分语法 S ‐> S a | S b a | a | S b c S | S b c b | c S | c b 我需要使用它来创建一些 SD 集,然后在解析表上使用它。 但是,在此之前,我应
是否有人引用了有关着色器编译器/图形驱动程序编译器内部工作原理的文档和研究? 最佳答案 编写一个普通的 C 编译器和编写一个着色器编译器没有太大的区别。编写编译器的标准书是所谓的“龙书”: http:
请问有没有人能给我解释一下句法导向的切线线性码和伴随码的区别。 它与使用编译器推导代码有关。 我知道它们是在程序中推导数学方程式的不同方法,但是,我不知道如何解释它们。 提前致谢。 问候。 最佳答案
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 7年前关闭。 Improve this questi
在编译器数据流分析中,变量的有效范围与其达到定义之间有什么区别?两者似乎都指的是同一件事... 最佳答案 它们是完全不同的东西,我建议您回过头来重新阅读那些使您感到困惑的定义。除其他事项外,对于使用给
我目前正在为一种非常有限的面向对象语言开发编译器。我想将所有值视为对象,这些值上的运算符将作为方法实现。编译器将程序转换为基于堆栈的虚拟机的汇编程序。 在编译期间,我将整数文字转换为特殊“整数”类的对
给定抽象语法树,我被要求编写一个程序来构建输入程序代码的数据流图。我在网上搜索数据流图的定义,发现一个代码段的数据流分析有很多事情要做。我想知道为给定代码构建数据流图到底需要绘制什么。很感谢任何形式的
一些随机的想法捕获了我,我就是无法摆脱它。我在想,既然现代处理器只是不同种类汇编语言的解释器,那么有没有办法创建一些直接在硬件中实现的高级语言解释器,使用一些 HDL 甚至直接使用逻辑门设计? 同时我
出现在代码生成的寄存器分配阶段的寄存器溢出或溢出代码是什么意思,编译器后端必须将变量分配到内存或寄存器? 最佳答案 Hardware registers是昂贵的(在芯片面积和寻址它们所需的指令位数方面
如果您的 bootstrap 语言编译器运行良好且可维护,为什么要更改它?例如,Go 在 1.5 版本中将其编译器重新编写为自托管,导致 compile times to become much sl
我在 Python Lisp 编译器和一些 C 链接器的源代码中看到了这个术语。 我的猜测是,修复只是 assembly 例程的一些包装,可确保对齐正确,但我对这里的任何事情都不确定。 最佳答案 “修
我对 VM 在运行时和编译时的优化感兴趣。我认为优化在编译时是最有效和最简单的。 然而,我的想法在某些情况下似乎是错误的。这在 Steve Yeggie's statement quoted by D
如果您正在构建一个编译器,那么在 AST 级别进行哪种优化是最好的? 最佳答案 大多数情况下,您无法在 AST 级别进行有趣的优化,因为您需要有关数据如何从程序的一个部分流向另一部分的信息。虽然数据流
我是一名优秀的程序员,十分优秀!