Default value of a function pointer in C++

2019-01-25 15:19发布

What is the default value of a function pointer in C++? (Apparently it can't be NULL, so what is it?)

How is this program supposed to behave and why?

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

int main()
{
    S s = S();
    s.f();   // What is the value of s.f?
}

5条回答
混吃等死
2楼-- · 2019-01-25 15:35

A function pointer can be NULL and you may assign NULL to it. Have a look here for instance:

#include <iostream>

using namespace std;

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

int main()
{
    S s = S();
    s.f = NULL;
    return 0;
}

I believe the way you call the constructor of the structure(with ()), f will be NULL.

查看更多
可以哭但决不认输i
3楼-- · 2019-01-25 15:46

In C++ (and C), pointers (regardless of type) do not have a default value per se; they take what ever happens to be in memory at the time. However, they do have a default initialised value of NULL.

Default Initialisation

When you don't explicitly define a constructor, C++ will call the default initialiser on each member variable, which will initialise pointers to 0. However, if you define a constructor, but do not set the value for a pointer, it does not have a default value. The behaviour is the same for integers, floats and doubles.

Aside

int main()
{
    S s = S();
    s.f();   // <-- This is calling `f`, not getting the pointer value.
}
查看更多
我命由我不由天
4楼-- · 2019-01-25 15:54

In your case the object s is zero-initialized which means the function pointer is NULL.

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

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

Output:

s.f is NULL

Online demo.

查看更多
放我归山
5楼-- · 2019-01-25 15:58

First any pointer can be null. It is the one universal truth about pointers. That said, yours will be null, but not necessarily for the reasons you may think;

C++11 § 8.5,p10

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

This is important because your declaration includes this :

S s = S();

By the definition of value initialization:

C++11 § 8.5,p7

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is called.

  • if T is an array type, then each element is value-initialized;

  • otherwise, the object is zero-initialized.

Which brings us to what it means for your object-type to be zero-initialized:

C++11 § 8.5,p5

To zero-initialize an object or reference of type T means:

  • if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression, converted to T (103)

  • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;

  • if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero- initialized and padding is initialized to zero bits;

  • if T is an array type, each element is zero-initialized;

  • if T is a reference type, no initialization is performed.

103) As specified in 4.10, converting an integral constant expression whose value is 0 to a pointer type results in a null pointer value.

The latter is the reason you're pointer is null. It will not be guaranteed-so by the standard given the same code, but changing the declaration of s to this:

S s;

Given a declaration like the above, a different path is taken through the standard:

C++11 § 8.5,p11

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2.

Which then begs the last question, what is default initialization:

C++11 § 8.5,p6

To default-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is an array type, each element is default-initialized;

  • otherwise, no initialization is performed.

查看更多
Animai°情兽
6楼-- · 2019-01-25 15:58

Function pointer can be NULL, this way you can indicate that they don't point to anything!

查看更多
登录 后发表回答