简体   繁体   English

带括号的typedef像“ typedef int(f)(void)”是什么意思? 它是功能原型吗?

[英]What does a typedef with parenthesis like “typedef int (f)(void)” mean? Is it a function prototype?

typedef int (fc_name) (void);

Here fc_name is any valid C symbol. fc_name是任何有效的C符号。

How different is this from a function pointer typedef ? 这与函数指针typedef有何不同?

It's a typedef to a function type. 它是函数类型的typedef The intent is to use it for function pointers, but in this case the syntax to use it would be: 目的是将其用于函数指针,但在这种情况下,使用的语法为:

int bar(void);

fc_name* foo = bar; /* Note the * */

Update: As mentioned in the comments to Jonathan Leffler's answer , the typedef can be used to declare functions. 更新:如对Jonathan Leffler的回答的评论中所述, typedef可用于声明函数。 One use could be for declaring a set of callback functions: 一种用途是声明一组回调函数:

typedef int (callback)(int, void*);

callback onFoo;
callback onBar;
callback onBaz;
callback onQux;

The first parentheses are superfluous - it is equivalent to: 第一个括号是多余的-等效于:

typedef int fc_name(void);

I don't think this does anything useful, though I can't get GCC to complain about it on its own. 我认为这没有任何用处,尽管我不能让GCC独自抱怨它。

This means that fc_name is an alias for a function type that takes no arguments and returns an int . 这意味着fc_name是不带任何参数并返回int的函数类型的别名。 It isn't directly all that useful, though you can declare, for example, the rand() function using: 尽管您可以使用以下方法声明rand()函数,但它并不是直接有用的:

fc_name rand;

You cannot use the typedef in a function definition. 您不能在函数定义中使用typedef

A pointer to function typedef would read: 指向函数typedef的指针将显示为:

typedef int (*fc_name)(void);

This code shows that the typedefs without the asterisk are not function pointers (addressing a now-deleted alternative answer): 这段代码显示不带星号的typedef不是函数指针(解决了现已删除的替代答案):

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1 x = function;
fc_name2 y = function;
fc_name3 z = function;

When compiled, 'gcc' says: 编译时,“ gcc”表示:

gcc -Wextra -Wall -pedantic -c -O x.c
x.c:10:1: error: function ‘x’ is initialized like a variable
x.c:11:1: error: function ‘y’ is initialized like a variable

And this code demonstrates that you can indeed use fc_name *var = funcname; 并且此代码演示了您确实可以使用fc_name *var = funcname; as suggested by jamesdlin : jamesdlin所建议:

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1  x_0 = function;
fc_name1 *x_1 = function;
fc_name2  y_0 = function;    // Damn Bessel functions - and no <math.h>
fc_name2 *y_1 = function;    // Damn Bessel functions - and no <math.h>
fc_name3  z   = function;

Using y0, y1 generates GCC warnings: 使用y0,y1会产生GCC警告:

x.c:12:11: warning: conflicting types for built-in function ‘y0’
x.c:13:11: warning: built-in function ‘y1’ declared as non-function

And, building on the comment from schot : 并且,基于schot的评论:

static int function(void)
{
    return 0;
}

typedef int   fc_name1 (void);
typedef int  (fc_name2)(void);
typedef int (*fc_name3)(void);

fc_name1  x_0 = function;   // Error
fc_name1 *x_1 = function;   // x_1 is a pointer to function
fc_name1  x_2;              // Declare int x_2(void);
fc_name1 *x_3 = x_2;        // Declare x_3 initialized with x_2

fc_name2  y_0 = function;   // Damn Bessel functions - and no <math.h>
fc_name2 *y_1 = function;   // Damn Bessel functions - and no <math.h>
fc_name1  y_2;              // Declare int y_2(void);
fc_name1 *y_3 = x_2;        // Declare y_3 initialized with y_2

fc_name3  z   = function;

Interesting - the dark corners of C are murky indeed. 有趣的是-C的黑暗角落确实很模糊。

Interesting! 有趣! A typedef declaration is a declaration with typedef as the storage class. typedef声明是一个以typedef作为存储类的声明。

typedef int   fc_name1 (void);   
// this defines a function type called fc_name1 
// which takes no parameter and returns int

later on, you could define a function like following, 以后,您可以定义如下函数,

fc_name1 myFunc;
// this is equivalent to the next line
// int myFunc(void);

You should be able figure this out from the c/c++ standard! 您应该能够从c / c ++标准中弄清楚这一点!

I've never before seen this done to a typedef name , but parentheses around the name of a function are useful to prevent its being expanded as a function-like macro of the same name. 我从未见过对typedef名称执行此操作,但是在函数名称周围加括号可防止将其扩展为相同名称的类似函数的宏。 For instance, the isxxx functions in ctype.h are defined as both functions and macros. 例如,将ctype.h中的isxxx函数定义为函数和宏。 This is so you can take a pointer to isalpha . 这样一来,您可以将指针指向isalpha But how does the C library define the out-of-line isalpha ? 但是C库如何定义离线isalpha Probably like this: 大概是这样的:

#include <ctype.h>

int
(isalpha)(int c)
{
    return isalpha(c);
}

The use of isalpha in the function body is expanded as a macro, the use in the function header isn't. 函数主体中isalpha的使用将扩展为宏,而函数标头中的使用则不是。

  1 #include <stdio.h>
  2 
  3 
  4 typedef int (fc_name)(void);
  5 
  6 
  7 
  8 int test_func1 ()
  9 {
 10     printf("\n test_func1 called\n");
 11 
 12     return 0;
 13 }
 14 
 15 int test_func2 (void)
 16 {
 17     printf("\n test_func2 called\n");
 18     return 0;
 19 }
 20 
 21 int handler_func(fc_name *fptr)
 22 {
 23     //Call the actual function
 24     fptr();
 25 }
 26 
 27 int main(void)
 28 {
 29     fc_name  *f1, *f2;
 30 
 31     f1 = test_func1;
 32     f2 = test_func2;
 33 
 34     handler_func(f1);
 35     handler_func(f2);
 36 
 37     printf("\n test complete\n");
 38 
 39     return 0;
 40 }

OUTPUT:- 输出:-

 test_func1 called

 test_func2 called

 test complete

So the typedef which I questioned about, (Line # 4 here) represents a function type and is not the same as function pointer typedef. 因此,我所质疑的typedef(此处为第4行)表示一个函数类型,并且与函数指针typedef不同。 This kind of typedef does not have much significance. 这种typedef没有太大的意义。 These are used as a style standard or simply to create obfuscation intentionally ;-) 这些用作样式标准或只是故意创建混淆;-)

The correct form is: 正确的形式是:

typedef int (*myfunc)(void);

You can define a function like follows: 您可以定义如下函数:

int helloword(void) {
    printf("hello, world\n");
}

and then define a variable point to this function: 然后定义一个指向该函数的变量:

myfunc hw_func;
hw_func = helloworld;

and call the function by the function pointer: 并通过函数指针调用该函数:

int ret = (*hw_func)();

The reason we need function pointer is that C language doesn't have predefined function pointer and use void * pointer to call a function is illegal in C language. 我们需要函数指针的原因是C语言没有预定义的函数指针,而在C语言中使用void *指针调用函数是非法的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM