这是问题的变体 Downcasting using the Static_cast in C++和 Safety of invalid downcast using static_cast (or reinterpret_cast) for inheritance without added members
关于 ~B 中的行为,我不清楚标准中的短语“B 实际上是 D 类型对象的子对象,结果指针指向 D 类型的封闭对象”。如果在 ~B 中转换为 D,此时它仍然是子对象吗? 以下简单示例显示了问题:
void f(B* b);
class B {
public:
B() {}
~B() { f(this); }
};
class D : public B { public: D() {} };
std::set<D*> ds;
void f(B* b) {
D* d = static_cast<D*>(b); // UB or subobject of type D?
ds.erase(d);
}
我知道转换是一扇通向灾难的大门,从 dtor 做任何类似的事情都是一个坏主意,但一位同事声称“代码是有效的并且工作正常。那个转换是完全有效的。评论明确指出不应取消引用它。”
我指出强制转换是不必要的,我们应该更喜欢类型系统提供的保护而不是注释。可悲的是,他是高级/首席开发人员之一,并且是一个假定的 C++“专家”。
我可以告诉他 Actor 是 UB 吗?
最佳答案
[expr.static.cast]/p11:
A prvalue of type “pointer to cv1
B,” where B is a class type, can be converted to a prvalue of type “pointer to cv2D,” whereDis a class derived (Clause 10) fromB, if a valid standard conversion from “pointer toD” to “pointer toB” exists (4.10), cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, andBis neither a virtual base class ofDnor a base class of a virtual base class ofD. The null pointer value (4.10) is converted to the null pointer value of the destination type. If the prvalue of type “pointer to cv1B” points to aBthat is actually a subobject of an object of typeD, the resulting pointer points to the enclosing object of typeD. Otherwise, the behavior is undefined.
那么,问题是,在 static_cast 时,指针是否实际指向“a B,它实际上是类型对象的子对象D”。如果是,则没有UB;如果不是,则行为未定义无论结果指针是否被取消引用或以其他方式使用。
[class.dtor]/p15 说(强调我的)
Once a destructor is invoked for an object, the object no longer exists
[basic.life]/p1 是这样说的
The lifetime of an object of type
Tends when:
- if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
- [...]
从这里开始,D 对象的生命周期在其析构函数被调用时就结束了,当然到 B 的析构函数开始执行时 - 这是在 D 的析构函数主体执行完毕之后。在这一点上,没有“D 类型的对象”留下这个 B 可以是它的子对象 - 它“不再存在”。因此,你有 UB。
Clang 与 UBsan 将 report an error在此代码上,如果 B 是多态的(给定一个虚函数),它支持这种阅读。
关于c++ - static_cast 从基析构函数到指向派生类的指针的安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28928590/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将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.你能做的最好的事情是:
说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时
我需要一个通过输入字符串进行计算的方法,像这样function="(a/b)*100"a=25b=50function.something>>50有什么方法吗? 最佳答案 您可以使用instance_eval:function="(a/b)*100"a=25.0b=50instance_evalfunction#=>50.0请注意,使用eval本质上是不安全的,尤其是当您使用外部输入时,因为它可能包含注入(inject)的恶意代码。另请注意,a设置为25.0而不是25,因为如果它是整数a/b将导致0(整数)。
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我