Typedef 函数 vs 函数指针

fon*_*ini 8 c c++ function-pointers declaration

我正在尝试使用 typedef 来理解函数声明。

这段代码在 C++ 中有什么作用?

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

fcn_t f;
fcn_t *pf;
ptr_t pf2;
Run Code Online (Sandbox Code Playgroud)

以我的理解:

  • fcn_t是函数的类型,所以用 withf是函数声明(不是定义),以后我可以像定义它一样定义它,就像void f(void) { blabla(); bleble(); }我声明了void f(void);而不是fcn_t f;;
  • fcn_t *是函数指针的类型,行pf是指针变量定义,并且pf是默认初始化的(假设代码摘录来自全局范围);
  • fcn_t*和之间没有区别ptr_t,因此我所说的一切都pf适用于pf2

我做对了吗?如果我标记它们,这三个声明中的任何一个都会改变其含义extern吗?如果将代码编译为 C 而不是 C++ 会发生什么变化?

Cur*_*ous 5

是的,您在这三个方面都是正确的。如果你标记它们,唯一会改变的extern是函数指针。函数声明extern在 C++中是默认的。

尝试编译以下程序

template <typename...>
struct WhichType;

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

// constexpr auto one = WhichType<fcn_t>{};
// constexpr auto two = WhichType<fcn_t*>{};
// constexpr auto three = WhichType<ptr_t>{};

fcn_t f;

void f() {}

int main() {
    f();
}
Run Code Online (Sandbox Code Playgroud)

取消注释注释行可能会给您一个编译器错误,告诉您WhichType实例正在实例化的类型,因此它应该向您显示您询问的所有三件事的确切类型。这是我从 Scott Meyers 的书“Effective Modern C++”中学到的一个技巧。


要测试声明是否为 extern ,请编写两个简单的实现文件,其中一个包含变量的定义

主程序

template <typename...>
struct WhichType;

typedef void fcn_t(void);
typedef void (*ptr_t)(void);

fcn_t f;

int main() {
    f();
}
Run Code Online (Sandbox Code Playgroud)

定义.cpp

void f() {}
Run Code Online (Sandbox Code Playgroud)

然后编译、链接和运行definition.cppmain.cpp(通过g++ -std=c++14 definition.cpp main.cpp然后./a.out)。如果声明不是 extern,则编译将失败并出现未定义的符号错误。