考虑这个程序:
#include <stdio.h>
struct S {
S() { print(); }
void print() { printf("%p\n", (void *) this); }
};
S f() { return {}; }
int main() { f().print(); }
据我所知,这里只构造了一个 S 对象。不会发生复制删除:首先没有要删除的复制,实际上,如果我明确删除复制和/或移动构造函数,编译器会继续接受程序。
但是,我看到打印了两个不同的指针值。发生这种情况是因为我平台的 ABI 在 CPU 寄存器中返回可复制的类型,例如这种类型,因此该 ABI 无法避免复制。即使完全优化函数调用,clang 也会保留这种行为。如果我给 S 一个重要的复制构造函数,即使它不可访问,那么我确实会看到两次打印相同的值。
对 print() 的初始调用发生在构造期间,即在对象生命周期开始之前,但在构造函数中使用 this 通常是有效的,只要它不是以需要完成构造的方式使用的——例如,不强制转换为派生类——据我所知,打印或存储它的值并不要求构造完成。
标准是否允许该程序打印两个不同的指针值?
注意:我知道标准允许该程序打印相同指针值的两种不同表示,从技术上讲,我没有排除这种可能性。我可以创建一个不同的程序来避免比较指针表示,但它会更难理解,所以如果可能的话我想避免这种情况。
最佳答案
T.C.在评论中指出这是标准中的一个缺陷。它是 core language issue 1590 .这是一个与我的示例略有不同的问题,但根本原因相同:
Some ABIs require that an object of certain class types be passed in a register [...]. The Standard should be changed to permit this usage.
current suggested wording将通过向标准添加新规则来涵盖这一点:
When an object of class type
Xis passed to or returned from a function, if each copy constructor, move constructor, and destructor ofXis either trivial or deleted, andXhas at least one non-deleted copy or move constructor, implementations are permitted to create a temporary object to hold the function parameter or result object. [...]
在大多数情况下,这将允许当前的 GCC/clang 行为。
有一个小的极端情况:目前,当一个类型只有一个删除的复制或移动构造函数,如果默认,根据当前的标准规则,该构造函数在删除时仍然是微不足道的:
12.8 Copying and moving class objects [class.copy]
12 A copy/move constructor for class
Xis trivial if it is not user-provided [...]
已删除的复制构造函数不是用户提供的,接下来的任何内容都不会使这样的复制构造函数变得不重要。所以按照标准的规定,这样的构造函数是微不足道的,as specified by my platform's ABI ,由于构造函数很简单,GCC 和 clang 在这种情况下也会创建一个额外的拷贝。在我的测试程序中添加一行代码就证明了这一点:
#include <stdio.h>
struct S {
S() { print(); }
S(const S &) = delete;
void print() { printf("%p\n", (void *) this); }
};
S f() { return {}; }
int main() { f().print(); }
这会使用 GCC 和 clang 打印两个不同的地址,即使建议的解决方案也需要打印两次相同的地址。这似乎表明,虽然我们将更新标准以不再需要完全不兼容的 ABI,但我们仍需要更新 ABI 以以与标准要求兼容的方式处理极端情况。
关于c++ - C++ 标准是否保证函数返回值具有常量地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38043288/
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到rubygems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案