相关文章推荐
绅士的洋葱  ·  3. ...·  7 月前    · 
simpleBLEPeripheral_TaskID = task_id ; // Setup the GAP VOID GAP_SetParamValue ( TGAP_CONN_PAUSE_PERIPHERAL, DEFAULT_CONN_PAUSE_PERIPHERAL ) ;

经查:
表示程序并不关心调用该函数后的返回值是什么,比如函数strcpy,我们直接用“strcpy(des_str, src_str);”这样的形式来调用。“(void)strcpy(des_str, src_str);”这样的形式还真不多见!
原因是这种写法不针对人,也不针对编译器,而是针对静态代码检测工具,它会把函数返回值作为一项检测标准。在某些大公司,比较重视代码规范,若在代码静态检测时需要检测该项。此时就需要用在被调用的函数(名)前加上“(void)”这种形式来告诉静态代码检测工具程序并非没有处理该函数的返回值,而是该处确实不需要处理它(该函数的返回值),不需要再对该处代码作此项检测。其实这和我们在代码中使用“#pragma warning (disable: XXXX)”的道理是一样的。

类似,在变量前加void:

void *fun(void *ud, void *ptr, int size){
(void) ud;
(void) size;
// 其他代码,未用到 ud 和 size 参数
fun() 函数中省略掉的代码没有使用到 ud 和 size 参数,这里有两个问题:一是既然用不到这两个参数,为什么不删去它们呢?再就是两个参数前的 (void) 类型转换有什么用呢?
项目比较复杂,但是我们知道再复杂的程序项目也是一行一行代码敲出来的,而且,在后续的开发中,可能会修改之前的设计。明白这一点,要回答第一个问题就简单了。
可能在之前的设计中,fun() 函数是用到了 ud 和 size 参数的,只是后来的设计发现 fun() 函数不必使用这两个参数,但是发现整个C语言项目由大量使用 fun() 函数的代码。
如果删去这两个参数,那么 fun() 函数的原型就改变了,开发人员将不得不逐个修改整个C语言项目中所有调用 fun() 函数的代码,这样的工作量巨大,极其容易给C语言项目引入 bug。因此,倒不如继续保留 fun() 函数的原型不变了。
另外,读者应该已经知道C语言是不支持重载的,因为如果该C语言项目需要使用 fun() 函数对接某些 API,那么fun() 函数就必须符合 API 指定的原型,因此 fun() 函数中有未使用的参数其实是“身不由己”的。
还有一种情况,fun() 函数可能是某个“函数家族”里的一个,该“函数家族”由一个统一的函数指针管理(为了方便,以及提高效率,实例可参考我之前文章。),因为“统一的函数指针”类型是固定的,所以 fun() 函数的原型必须符合该函数指针的原型,所以,即使 fun() 函数用不到 ud 和 size 参数,也是不能将其删除的,否则就无法通过“统一的函数指针”调用 fun() 函数了。

为什么要在未使用的参数前添加 (void) 呢?
为什么使用void(val);?

作用是避免编译器警告。

声明/定义了但没使用的变量,在编译时会生成warning。

如果项目里是打开了-Werror选项,会将warning视为error,这样的话无法通过编译。

所以需要用这种方法绕过无关紧要的warning。

启动App进程 Activity启动过程的一环是调用ActivityStackSupervisor.startSpecificActivityLocked,如果App所在进程还不存在,首先调用AMS的startProcessLocked: void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? ProcessRecord app = mService.getPr 我们知道,在定义函数时,在函数名前的“void”表示该函数没有返回值。但在调用时,在函数名前加“(void)”的作用又是什么呢? 最明显的一点就是表示程序并不关心调用该函数后的返回值是什么,比如函数strcpy,我们直接用“strcpy(des_str, src_str);”这样的形式来调用。“(void)strcpy(des_str, src_str);”这样的形式还真不多见! 原因是这种... 首先,为什么要使用extern “C”修饰符? C++调用其它语言的函数,由于编译器生成函数的机制不一样,所以需要经过特殊处理,才可以调用。调用C语言的函数,需要在函数声明的地方语句extern “C”。如果不使用该语句,在链接的时候,编译器就会报以下这种错误。 Test.obj : error LNK2019: 无法解析的外部符号 “void __cdecl DeleteStack(struct _Node *)” (?DeleteStack@@YAXPAU_N Js函数调用的方式有如下几种情况: (1)具名函数直接调用 代码如下:function foo()  {  }  foo(); (2)匿名函数通过引用来调用 代码如下:  fooRef = function()  {  }fooRef(); (3)没有引用的匿名函数调用1 代码如下:(function() {}()); (4)没有引用的匿名函数调用2 代码如下: (function() { })();   (5)没有引用的匿名函数调用3  代码如下: void function() { }(); 图1.1,图1.2表明了这两种表达式的运算过程是不一样的,图1.1中是用强制运算符使函数调用运算 我们知道,在定义函数时,在函数名前的“void”表示该函数没有返回值。但在调用时,在函数名前加“(void)”的作用又是什么呢? 最明显的一点就是表示程序并不关心调用该函数后的返回值是什么,比如函数strcpy,我们直接用“strcpy(des_str, src_str);”这样的形式来调用。strcpy()原型声明:char *strcpy(char* dest, const... 1 数据结构1.1 Closure 闭包1.2 Proto 函数原型1.3 UpVal 外部局部变量(upvalue)1.4 LocVar 局部变量信息1.5 SParser 语法分析所需要的结构1.6 Zio 读写流对象1.7 Mbuffer 缓冲对象1.8 lua_Debug 调试信息1.9 CallInfo 函数调用信息1.10 lua_longjmp 跳转信息1.11 CallS 调用函数结构(f_call的参数)1.12 CCallS 调用C函数结构 (f_Ccall的参数)2 闭包相关API2. 看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解。1.理解函数声明为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用位于地址0的子例程。调用语句如下:(*(void (*)())0)();胆颤了吧?首先我们从函数的声明说起:有如下一个函数void func(){...}那么,要想声明一个函数指针,指向这类函数,怎样声明呢?如下:void (*pf)();那么,想要将... 协议是一系列的通信标准,通信双方按照共同的标准进行数据的传输。 其实说白了协议就是在给每一层的数据进行封装打包,假设收集的数据是一个数组,那就再数组的前面或者后面或者两者上一些冗余的数据,包括包头包尾校验码等。(物理层除外... void属于函数类型中的无类型函数之对应的还有实型(float,double),整型(int),布尔型(bool)和字符型(char)。 在介绍void之前先介绍“返回值”: 就如字面上的意思,返回值是子函数返回给主函数的一个值,主函数将实参传递给子函数的形参,经过子函数的函数体运算后得到一个值,再通过return将值传递给主函数。 主函数可以利用变量将返回值储存在已定义的变量中进行保存。值得一提是子函数的返回值类型是和函数声明中的参数类型一致的。 现在,再了解“返回值”后我们来着重介绍一下vo C语言里面的内联函数(inline)与宏定义(#define)探讨先简明扼要,说下关键:1、内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快。2、内联函数可以调试,而宏定义是不可以调试的。内联函数与宏本质上是两个不同的概念如果程序编写者对于既要求快速,又要求可读的情况下,则应该将函数冠以inline。下面详细介绍一下探讨一下内... BLE连接参数更新过程详解 有关连接参数概念和作用我们在 Generic Access Profile (GAP) 一章中已经详细讲解过,这一章演示如何通过修改simple_peripheral例程实现连接参数更新,并分析程序流程。 连接参数更新过程中都是主机发起的,从机只能被动的接收主机设置的参数,这个过程发生在连接的时候,当连接之后如果主机设置的参数不利于从机,从机可以发送