C++ 与 C 中的函数指针

相关代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     const char *message1 = "Thread 1";
     const char *message2 = "Thread 2";
     int  iret1, iret2;

     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     if(iret1)
     {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);
         exit(EXIT_FAILURE);
     }

     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
     if(iret2)
     {
         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
         exit(EXIT_FAILURE);
     }

     printf("pthread_create() for thread 1 returns: %d\n",iret1);
     printf("pthread_create() for thread 2 returns: %d\n",iret2);

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     exit(EXIT_SUCCESS);
}

void *print_message_function( void *ptr )
{
     char *message;
     message = (char *) ptr;
     printf("%s \n", message);
}

疑惑地方

在函数 pthread_create(pthread_t * thread, const pthread_attr_t * attr,void * (*start_routine)(void *), void *arg);
其中 void * (*start_routine)(void *) 这个参数是 "函数指针"
而根据函数 void *print_message_function( void *ptr );原型来看这是一个 返回任何指针类型的函数,不是函数指针,而且这个函数的实现中并没有返回值. 但是可以使用gcc编译通过,没有任何异常, 有哪位知道这是为什么吗? 或者给出一个参考链接?

我所知道的类似void *print_message_function( void *ptr ); 函数的用法是这样的


 #include<stdio.h>

 void *test_f(int *n);
 
 int main(void) 
{
         int test_num = 32;
         int *test_p = &test_num;
         int *ret_v = test_f(test_p);
         printf("%d \n",*ret_v);
         return 0;
 }

void *test_f(int *n) 
{
         *n = *n + 1;
         return n;
}
阅读 2.5k
2 个回答

先说一个问题:你的最后一个函数void *test_f(int *n)中的return语句有问题,应是return &n;

接下来回答你的疑惑——

首先你的void *print_message_function( void *ptr )函数的实现中,没有显式使用调用return语句,据我对一些编译器的了解,编译器会自动设置一个返回值并返回,通常是0。编译时这样的情况通常会报出warning错误的,如果你没有看到相关报错,可能是编译器禁用了相关报错。

然后是函数指针。C里边,数组和函数有一个共同的有趣特性,如下代码所示:

#include <stdio.h>

int list[10];
int func() {}

int main()
{
    printf("%x\n", list);
    printf("%x\n", &list);
    printf("%x\n", func);
    printf("%x\n", &func);
    printf("%x\n", sizeof func);
    return 0;
}

这段代码在我的电脑(CentOS 7.4, gcc 4.8.5)上运行结果如下:

601060
601060
40051d
40051d
1

从前四行可以看出,不管是数组和函数的标识符本身,还是对它们取地址,其结果是一样的。从这种意义上讲,函数名就是一个类似于指针的存在,函数名本身和指向这个函数的指针在使用上是具有相似性的。但是sizeof func的值竟然是1,这也说明函数又绝对不是简单的指针。至于C语言的函数本质究竟是什么样的,由于我对C语言的标准、编译原理、GCC实现原理没有什么研究,因此还解释不了这个问题,但以上应该基本可以回答pthread_create调用函数这个问题了。

start_routine 参数的原型是

void *(*start_routine) (void *)

不是

void (start_routine)(void)

void (start_routine)(void*)

请参照文档 http://man7.org/linux/man-pag...


默认情况下,gcc 要开启 -Wreturn-type 才会警告 “在非 void 返回值函数中没有 return 语句”,
一般建议打开 -Wall 选项,可将所有警告当成编译错误,如

gcc -Wall a.c

若使用 g++ 编译,则不必显式指定 -Wreturn-type,因它规定要写 return(对非 void 返回值)。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏