草庐IT

c++ - 如果值未更改,是否允许更改对象的底层字节?

coder 2024-02-22 原文

如果值本身未更改,是否允许更改对象的底层字节?

那么,例如,这个代码片段可以打印“不同”吗?

int a = 0;
char b[sizeof(int)];

memcpy(b, &a, sizeof(int));
if (memcmp(b, &a, sizeof(int)) {
    printf("differ\n");
}

这是让我提出这个问题的问题:Is delete allowed to modify its parameter? ,查看问题下方的评论,例如,这个 comment来自 Johannes Schaub:

What rule forbids changing the internal bits of an int? As far as I know, the implementation is even allowed to make int a = 0; /* test bits of 'a' now /; / test bits of 'a' now*/ have two different bits each time

最佳答案

通常,memcpymemcmp 严格按字节工作,因此它们不能不同。

(C++11) 标准的一种解读似乎表明 可能 int 可能与另一个不同(根据 memcmp) 如果允许整数具有对值没有影响的填充字节,则您刚刚从中分配了它。

根据您的代码,使用 int 和类似大小的 char 缓冲区似乎是可行的:

int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));

a 中的填充字节(如果有的话)以底层值不变的方式进行更改。这可能导致memcmp失败。

可以在 C++11 3.9.1 Fundamental types 中找到该特定读物:

For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types.

这允许在非字符类型中填充位的可能性,并且标准中没有任何内容明确阻止这些位随时更改。

但是,在同一部分中,它将字符和有符号或无符号整数归为“整数类型”类别,并指出:

representations of integral types shall define values by use of a pure binary numeration system. (footnote 49) [Example: this International Standard permits 2’s complement, 1’s complement and signed magnitude representations for integral types. —end example ]

脚注 49 状态:

A positional representation for integers that uses the binary digits 0 and 1, in which the values represented by successive bits are additive, begin with 1, and are multiplied by successive integral power of 2, except perhaps for the bit with the highest position. (Adapted from the American National Dictionary for Information Processing Systems.)

这似乎根本没有为这些类型中的填充位留下可能性,因为它非常明确地调用了 连续 位和 2 的幂,唯一特别提到的异常(exception)是高位(用于决定三种可能编码的符号)(a).

所以我怀疑 memcmp 不会在使用相同内存块和大小的 memcpy 之后立即失败。

当然,这与您链接到的问题完全无关,因为有一个中间操作 delete,它可以自由更改底层位模式。这种情况与:

int a = 0;
char b[sizeof(int)];
memcpy(b, &a, sizeof(int));
a = 42; // intervening operation

之后 memcmp 几乎可以保证将这两个内存块视为不同的。


(a) 令人讨厌的是,有一个 潜在的读数允许填充位,同时仍然满足上面提到的“连续”位和二次幂 - 如果填充位位于底层位模式的低端(离符号最远)。如果允许那个,那么,是的,memcpy 之后的memcmp 可以报告差异。

关于c++ - 如果值未更改,是否允许更改对象的底层字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45839129/

有关c++ - 如果值未更改,是否允许更改对象的底层字节?的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - Ruby on Rails 迁移,将表更改为 MyISAM - 2

    如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设

  3. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  4. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  5. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  9. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  10. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

随机推荐