【问题标题】:Will function pointers always initialize to NULL?函数指针是否总是初始化为 NULL?
【发布时间】:2010-10-07 00:20:01
【问题描述】:

我正在使用 MSVC,下面的代码似乎没有崩溃,并且函数指针被编译器初始化为 NULL。

int (*operate)(int a, int b);
int add(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

int main()
{


    if(operate) //would crash here if not NULL
    {
        cout << operate(5,5);
    }

    operate = add;
    if(operate)
    {
        cout << operate(5,5);
    }

    operate = subtract;
    if(operate)
    {
        cout << operate(5,5);
    }
    return 0;
}

看来 MSVC 将函数指针初始化为 NULL,但如果我在 Linux 中的 gcc 上构建它,它也会为 NULL 吗?它是传统的还是特定于 MSVC 的,无论我走到哪里,我都可以依赖它为 NULL 吗?

谢谢

【问题讨论】:

  • 将指针设为局部变量,您会发现它不会。您有一个未初始化的全局变量,编译器通常会将其放入零初始化的 .bss 段中。
  • C 或 C++,它们是不同的语言。
  • @Jeff:编译器把它放在哪里无关紧要。如果它有静态存储时长,则需要进行零初始化。
  • Will a function pointer be NULL by default? 比较(这不是重复的,但相关并表明 Milo 需要在他的问题标题上多做一些工作)。
  • @Jeff:标准当然需要它,并且已经有 20 多年了。这是任何 C 程序员都应该知道的最基本的事情之一。

标签: c++ c


【解决方案1】:

operate 被初始化为 NULL 因为它是一个全局变量,而不是因为它是一个函数指针。所有具有静态存储持续时间的对象(包括全局变量、文件级 static 变量和函数中的 static 变量)如果没有给出初始化器,则初始化为 0 或 NULL。

[针对 Jim Buck 的评论进行编辑:] 在 C++ 中,语言标准的第 3.6.2/1 条保证了这一点,它开始于:

具有静态存储持续时间的对象 (3.7.1) 应为零初始化 (8.5) 在任何其他初始化之前 发生。零初始化和 用常数初始化 表达式统称为 静态初始化;所有其他 初始化是动态的 初始化。

我希望 C 也有同样的行为,因为 C++ 旨在在大多数情况下与它兼容,尽管我没有它的标准。

[EDIT #2] 正如 Jeff M 在评论中指出的那样,重要的是要意识到自动存储持续时间的变量(即“普通”局部变量)是 not 自动零初始化:除非给定初始化器,或者它们由构造函数赋值,否则它们最初将包含随机垃圾(无论该位置已经存在于内存中的什么)。因此,初始化所有变量是一个好习惯——它不会有坏处,但会有所帮助。

【讨论】:

  • @Jim:确实,它们在 C++ 中得到了保证。我将在我的帖子中添加对标准中相关段落的引用。
  • @Jeff:无论编译器是否选择将它们放在.bss 段中,它们必须初始为零。这是 C 和 C++ 语言标准所要求的。
  • C99 规范第 6.9.2 节涵盖了这一点——它与 C++ 相同
  • @Matt:不知道你是如何得出这样的印象,即我建议 C 的情况有所不同。我只是说我不确定它是否相同。不知道我怎么能更清楚...?
  • @Jim:我明白为什么这会卡在你的记忆中了 :) C++ 编译器因错误地实现语言规范而臭名昭著——我猜是编译器或链接器错误导致了你的悲痛。不知道这是否会使它变得更好或更糟...... :)
猜你喜欢
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-07
  • 1970-01-01
  • 2019-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多