C++中函数指针的默认值

Meh*_*dad 6 c++ function-pointers

C++中函数指针的默认值是什么?(显然它不可能NULL,所以它是什么?)

这个程序应该如何表现?为什么?

struct S { void (*f)(); };

int main()
{
    S s = S();
    s.f();   // What is the value of s.f?
}
Run Code Online (Sandbox Code Playgroud)

Who*_*aig 18

首先任何指针都可以为null.这是关于指针的一个普遍真理.也就是说,你的是空的,但不一定是你想的原因;

C++11§8.5,p10

初始值为空集括号的对象,即(),应进行值初始化.

这很重要,因为您的声明包括:

S s = S();
Run Code Online (Sandbox Code Playgroud)

通过值初始化的定义:

C++11§8.5,p7

对值类型T的对象进行值初始化意味着:

  • 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的) ;

  • 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数.

  • 如果T是数组类型,那么每个元素都是值初始化的;

  • 否则,该对象被零初始化.

这让我们了解了对象类型被零初始化的意义:

C++11§8.5,p5

零初始化T类型的对象或引用意味着:

  • 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T (103)

  • 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;

  • 如果T是(可能是cv限定的)并集类型,则对象的第一个非静态命名数据成员将进行零初始化,并将填充初始化为零位;

  • 如果T是数组类型,则每个元素都是零初始化的;

  • 如果T是引用类型,则不执行初始化.

103)如4.10中所述,将值为0的整型常量表达式转换为指针类型会产生空指针值.

后者是你指针为空的原因.它不会得到保证 - 所以给定相同代码的标准,但改变声明s:

S s;
Run Code Online (Sandbox Code Playgroud)

鉴于上述声明,标准采用了不同的路径:

C++11§8.5,p11

如果没有为对象指定初始化程序,则默认初始化该对象; 如果未执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值.[注意:具有静态或线程存储持续时间的对象是零初始化的,请参见3.6.2.

然后讨论最后一个问题,什么是默认初始化:

C++11§8.5,p6

默认初始化T类型的对象意味着:

  • 如果T是一个(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

  • 如果T是数组类型,则每个元素都是默认初始化的;

  • 否则,不执行初始化.


Naw*_*waz 6

在您的情况下,对象s是零初始化,这意味着函数指针是NULL.

struct S { void (*f)(); };

int main()
{
    S s = S();
    if ( s.f == NULL)
       std::cout << "s.f is NULL" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

s.f is NULL
Run Code Online (Sandbox Code Playgroud)

在线演示.