我正在尝试使用typedef来理解函数声明。
这段代码在C ++中做了什么?
typedef void fcn_t(void);
typedef void (*ptr_t)(void);
fcn_t f;
fcn_t *pf;
ptr_t pf2;
根据我的理解:
fcn_t
是函数的类型,因此带有f
的行是函数声明(不是定义),我以后可以将它定义为{ {1}}就像我宣布void f(void) { blabla(); bleble(); }
而不是void f(void);
一样; fcn_t f;
是函数指针的类型,fcn_t *
的行是指针变量 definition ,pf
是默认初始化的(假设代码摘录来自全球范围); pf
和fcn_t*
之间没有区别,因此我所说的关于ptr_t
的所有内容都适用于pf
。我做对了吗?如果我将它们标记为pf2
,那三个声明中的任何一个都会改变它的含义吗?如果代码编译为C而不是C ++,会发生什么变化?
答案 0 :(得分:3)
是的,你在所有三个方面都是正确的。如果你标记它们extern
,唯一会改变的是函数指针。函数声明在C ++中默认为extern
。
尝试并编译以下程序
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();
}
取消注释注释行可能会给您一个编译器错误,告诉您实例化WhichType
实例的类型,因此它应该显示您询问的所有三件事的确切类型。这是我从Scott Meyers的书“Effective Modern C ++”中汲取的一个技巧。
要测试声明是否为extern,请编写两个简单的实现文件,其中一个包含变量的定义
<强>的main.cpp 强>
template <typename...>
struct WhichType;
typedef void fcn_t(void);
typedef void (*ptr_t)(void);
fcn_t f;
int main() {
f();
}
<强> definition.cpp 强>
void f() {}
然后编译,链接并运行definition.cpp
和main.cpp
(通过g++ -std=c++14 definition.cpp main.cpp
然后./a.out
)。如果声明不是extern,那么编译将失败并出现未定义的符号错误。
答案 1 :(得分:-1)
以下是这些typedef
#include <stdio.h>
typedef void fcn_t(void);
typedef void (*ptr_t)(void);
fcn_t f;
fcn_t *pf;
ptr_t pf2;
void
f(void)
{
printf("I am void\n");
}
void
vSayHi(void)
{
printf( "Hi\n" );
}
int
main(void)
{
pf2 = vSayHi;
pf2();
pf = vSayHi;
pf();
f();
return 0;
}
输出:
Hi
Hi
I am void