【问题标题】:For what object pointer values does the pointer to member operator invoke undefined behavior?对于哪些对象指针值,指向成员运算符的指针会调用未定义的行为?
【发布时间】:2012-07-17 00:51:33
【问题描述】:

当使用指向成员运算符 (->*) 的指针时,对象的哪些指针值会调用未定义的行为?

具体来说,如果所讨论的成员函数不访问任何成员并且不是虚拟的,是否存在以下任一错误?

  • 空指针
  • 指向已删除对象的指针

This question 类似,但讨论的是常规成员函数调用。

用代码来说明:

#include <iostream>     
using namespace std;     

class Foo {     
public:     
  int member(int a)     
  {     
    return a+1;     
  }     
};     

typedef int (Foo::*FooMemFn)(int);     

int main(int argc, char** argv)     
{     
  FooMemFn funcPtr = &Foo::member;     
  Foo *fStar = 0;     
  Foo *fStar2 = new Foo();     
  delete fStar2;     

  int a1 = (fStar->*funcPtr)(4);  //does this invoke UB?                                                                                                                                                                                                                             
  int a2 = (fStar2->*funcPtr)(5); //what about this?                                                                                                                                                                                                                               

  cout<<"a1: "<<a1<<"  a2: "<<a2<<endl;     

  return 0;     
}

关于未定义行为的问题是关于 C++ 标准的问题,因此我正在寻找对 C++ 标准部分的具体参考。

【问题讨论】:

  • 任何无效指针都会调用 UB。空指针无效,已删除指针也是如此。未初始化的也是如此。

标签: c++ undefined-behavior standards-compliance pointer-to-member


【解决方案1】:
int a1 = (fStar->*funcPtr)(4);  //does this invoke UB?  
int a2 = (fStar2->*funcPtr)(5); //what about this? 

是的。 两个语句都调用 UB
因为它们等价于:

fStar->member(4);
fStar2->member(5);

分别。

【讨论】:

  • 你能指出标准中的任何语言来达到这个效果吗? ->* 的实际定义似乎比所述等价更复杂。
  • @Soverman,我现在没有任何标准参考。但是成员函数指针用于调用带有调用者对象/指针的函数。可能是函数指针可能有一个额外的间接,但这不会改变机制。直接调用或使用函数指针并不完全相同,而是逻辑等价的。
  • 另一种逻辑等价是成员函数只是一个函数,它以指向类的指针作为其第一个参数加上一些语法糖。但如果情况确实如此,那么这里就不会有问题,因为该指针实际上永远不会被取消引用。这就是为什么我正在寻找比您目前的答案更多的细节,最好是标准参考的形式。
  • @Soverman:在空指针上调用成员函数(不管调用方法如何)是未定义的行为。指向成员的指针的语言必须比直接调用的语言更复杂,因为成员函数不能为空,但指向成员的指针可以。关于您的评论,成员函数 一个函数,它接受一个指向带有一些语法糖的对象 (this) 的指针,但标准声明它是未定义的。请注意,在许多情况下您可以侥幸逃脱(非虚拟功能无法访问其他成员),但不能保证。
  • @DavidRodríguez-dribeas 您完全正确,UB 是由标准定义的。我只是想解释为什么我在寻找对标准的参考,而不是 iammilind 当前的答案。我也会对“如果不是 UB 就不可能实现 C++ 编译器,因为......”形式的答案感到满意。
猜你喜欢
  • 2014-01-02
  • 1970-01-01
  • 2011-05-17
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多