关于linux下sizeof(fun/*fun/&fun)的一些讨论

本文探讨了C语言中函数指针和sizeof操作符的使用,解释了函数指针如何存储函数入口地址,以及sizeof操作符在不同场景下的应用结果。通过分析实例代码,揭示了sizeof(*f1)=1的原因,并讨论了函数指针类型、内存布局和编译器行为之间的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

讨论内容主要来自西电开源社区:http://linux.xidian.edu.cn/bbs/forum.php

的这个帖子:http://linux.xidian.edu.cn/bbs/forum.php?mod=viewthread&tid=636#lastpost



问题:


A:存在函数 intf1(void){return 0;} cout<<sizeof(*f1)<<endl; 采用GCC编译器求出的结果为 1 。 不懂,求高手解释,小弟菜鸟一个,求带。


B:f1是代码段的一个地址,代码段地址是uint8 *类型的,所以对它解引用的话实际上是得到一个uint8类型的数,所以就是1了。


A:表示有些疑问,仅靠段地址如何确定函数入口呢?


B:额,应该是代码段的指令地址。代码在编译后,对cpu来说是没有函数这个概念的,调用函数时都是从具体的地址开始的,汇编语言里的call指令参数就是地址。当代码加载进内存时每一条指令都是有具体地址的,可以了解下setjmp和longjmp函数,使用静态库和动态库也是这么回事。


A:这些我明白,call等效于cs和ip入栈,然后读入新的ip。刚才想了一下,程序内函数应该是段内短调用,不需要对cs进行操作,f1存放的应该是ip的内容,那么*f1应该就是ip所指的内存字节里的指令,所以sizeof(*f1)=1,由于是短调用,所以sizeof(f1)也是1


B:f1是函数指针,凡是指针都是unsigned long类型的,所以在32位机上sizeof(f1)是4,在64位机上是8;
另在Linux里是没有cs一说的(对我们来说是透明的,内核实现),压栈的只有EIP,所以也就不存在短调用长调用一说;
指令是以字节为单位的,所以就是1了。


嗯,就是这个结果,f1, *f1和&f1的值是一样的,但前两个用sizeof操作符都是1。将f1赋值给f,sizeof(f)又是4,*f是1,这跟前面的推断是一样的,f1到底是个什么东东啊,这完全违背C语言的常理啊!肯定是编译器的问题,sizeof操作符就编译器实现的,就不知道他是如何对待函数标示符的。



C:很久之前看到过一个文章说的是,假如func是函数名,则*func , &func , func 都可以作为func来使用。



搜一下相关的帖子可以发现,sizeof(函数名) 的执行结果与编译器相关,是编译器的扩展,VC 等一些 IDE 提供的编译器会报错,而 Gcc 好像提供了这个扩展功能,能够正确通过,因为在标准中规定 sizeof() 的参数不能是函数名,但可以是指向函数的指针。
http://blog.youkuaiyun.com/w57w57w57/article/details/6626840http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/88e0c0ea-cc96-4ee4-9393-1afc255afc51/



给个链接, 虽然不能解决所有问题,但还是值得一看的
http://blog.pfan.cn/whyhappy/6030.html


各位,参考 http://zhidao.baidu.com/question/315750027.html Origin_in是个大神啊!膜拜




/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "spi.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include<stdio.h> #include "string.h" uint8_t fun[32]; int rev=0; int press=0; void update_pwm(uint8_t mode); void put_char(uint8_t ch) { while(!(USART1->ISR & (1<<7))){} USART1->TDR=ch; } const uint8_t number[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; uint8_t buf[2]={}; volatile uint8_t a=0; void display(uint8_t pos,uint8_t num) { buf[0]=1; buf[1]=number[a]; HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,0); HAL_SPI_Transmit(&hspi2,buf,2,10); HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,1); } //void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //{ // rev=1; //// a=fun[0]%4; //// display(0x01,a); //// update_pwm(a); void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {rev=1; HAL_UARTEx_ReceiveToIdle_IT(&huart1,fun,32); } /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void SystemPower_Config(void); /* USER CODE BEGIN PFP */ void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin) { press=1; // a=(a+1)%4; // display(0x01,a); // update_pwm(a); } void update_pwm(uint8_t a) { switch(a) { case 0: TIM3->CCR1 = 0; break; case 1: TIM3->CCR1 = 500; break; case 2: TIM3->CCR1 = 750; break; case 3: TIM3->CCR1 = 999; break; } } /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* Configure the System Power */ SystemPower_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_SPI2_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_UARTEx_ReceiveToIdle_IT(&huart1,fun,32); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { if(rev==1) { rev=0; a=(fun[0]-'0')%4; HAL_UART_Transmit(&huart1,fun,32,10); } if(press==1) { press=0; a=(a+1)%4; } display(0x01,a); update_pwm(a); memset(fun,0,sizeof(fun)); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE4) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_PCLK3; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } /** * @brief Power Configuration * @retval None */ static void SystemPower_Config(void) { /* * Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral */ HAL_PWREx_DisableUCPDDeadBattery(); /* USER CODE BEGIN PWR */ /* USER CODE END PWR */ } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ 为什么fun打印没东西
最新发布
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值