我读过 this article about C/C++ strict aliasing .我认为这同样适用于 C++。
据我了解,严格别名用于重新排列代码以实现性能优化。这就是为什么两个不同(在 C++ 情况下不相关)类型的指针不能引用相同的内存位置。
这是否意味着只有修改内存才会出现问题?除了可能的问题with memory alignment .
例如,处理网络协议(protocol),或反序列化。我有一个字节数组,动态分配并且数据包结构正确对齐。我可以reinterpret_cast 它到我的数据包结构吗?
char const* buf = ...; // dynamically allocated
unsigned int i = *reinterpret_cast<unsigned int*>(buf + shift); // [shift] satisfies alignment requirements
最佳答案
这里的问题不是严格的别名,而是结构表示要求。
首先,在char、signed char 或unsigned char 和任何 之间使用别名是安全的其他类型(在您的情况下,unsigned int。这允许您编写自己的内存复制循环,只要它们是使用 char 类型定义的。这是由 C99 (§6.5) 中的以下语言授权:
6. The effective type of an object for an access to its stored value is the declared type of the object, if any. [Footnote: Allocated objects have no declared type] [...] If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
7. An object shall have its stored value accessed only by an lvalue expression that has one of the following types: [Footnote: The intent of this list is to specify those circumstances in which an object may or may not be aliased.]
- a type compatible with the effective type of the object,
- [...]
- a character type.
类似的语言可以在 C++0x 草案 N3242 §3.11/10 中找到,尽管在分配对象的“动态类型”时并不清楚(我希望能进一步引用动态是什么type 是一个 char 数组,POD 对象已作为具有适当对齐方式的 char 数组复制到该数组。
因此,别名在这里不是问题。然而,严格阅读该标准表明,C++ 实现在选择 unsigned int 的表示形式方面具有很大的自由度。
作为一个随机示例,unsigned int 可能是一个 24 位整数,用四个字节表示,其中散布着 8 个填充位;如果这些填充位中的任何一个与某个(常量)模式不匹配,它就会被视为陷阱表示,并且取消引用指针将导致崩溃。这是一个可能的实现吗?也许不是。但是从历史上看,系统有奇偶校验位和其他奇怪的东西,因此直接从网络读取到 unsigned int,通过严格阅读标准,是不是犹太洁食。
现在,填充位的问题在当今大多数系统上主要是一个理论问题,但值得注意。如果你打算坚持使用 PC 硬件,你真的不需要担心它(但不要忘记你的 ntohl - endianness 仍然是一个问题!)
当然,结构使情况变得更糟 - 对齐表示取决于您的平台。我曾在一个嵌入式平台上工作,其中所有类型的对齐方式均为 1 - 结构中从未插入任何填充。在多个平台上使用相同的结构定义时,这可能会导致不一致。您可以手动计算出数据结构成员的字节偏移量并直接引用它们,或者使用特定于编译器的对齐指令来控制填充。
因此,从网络缓冲区直接转换为 native 类型或结构时必须小心。但在这种情况下,别名本身不是问题。
关于c++ - 我是否正确理解 C/C++ 严格别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7321513/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我在OSX上(如果重要的话)。如果我使用RVM安装Ruby,它会默认将Bundler安装到@globalgemset假设我想要一个不同版本的bundler。我假设我需要做的就是执行geminstallbundler--version但是,这会将bundler安装到默认gemset并且RVM不会为其设置路径。因此,如果我键入bundler,它仍会启动一个与Ruby一起安装到@global中的bundler两个问题:如何将bundler安装到@globalgemset。将bundler安装到@globalgemset中的模式是否正确,或者我遗漏了什么 最佳答案