热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

如果未检查函数返回值,如何强制编译错误?

如何解决《如果未检查函数返回值,如何强制编译错误?》经验,为你挑选了1个好方法。

如果我正在使用特定功能而不检查其返回值,我希望编译器发出错误。

我在Eclipse中使用GCC。

例如 :

int fun (){ return 3;}

void main ()
{
   printf("%d",fun ());
}

我调用该函数fun并打印返回值,但不检查返回值。相反,我想强制执行以下操作:

int ret=fun();
if(ret != some_value) { /* Do something */ }
printf("%d",fun ());

这可能吗?



1> klutt..:

您不能强制进行适当的检查

我认为没有任何方法可以按照您想要的方式进行。毕竟,在该语句中,printf("%d",fun ())您实际上是fun()通过将返回值发送到另一个函数来检查返回值。当然,printf并没有真正“检查”返回值,但是您可以这样使用它:

void exit_if_fun_returns_negative_value(int val) { if(val<0) exit(EXIT_FAILURE); }

int main(void)
{
    exit_if_fun_returns_negative_value(fun());
}

但是没有办法使编译器理解此printf语句与您的语句之间的区别。我假设您想强迫程序员将返回值保存在变量中,但是我不知道该怎么做,即使您可以这样做,也不能确保正确的检查。看看这个例子:

char *array;
void *ptr;
ptr = realloc(array, 20);
strcpy(array, "Hello, World!");

注意我们如何保存返回值,ptr但是由于我们没有做类似的事情,if(ptr == NULL) exit(EXIT_FAILURE);所以没有意义。

但是您可以防止完全忽略返回值

但是,有一种方法可以防止根本不使用返回值的语句(当然,这与实际检查不一样)。

据我所知,没有便携式的方法可以做到这一点。您将不得不依赖编译器扩展。Gcc有这样的扩展。

__attribute__ ((warn_unused_result)) int foo (void) 
{
    return 5;
}

int main(void)
{
    foo();
}

进行编译将生成以下警告:

$ gcc main.c
main.c: In function ‘main’:
main.c:9:5: warning: ignoring return value of ‘foo’, declared with attribute warn_unused_result [-Wunused-result]
    9 |     foo();
      |     ^~~~~

为了将其视为错误,请使用 -Werror

$ gcc main.c -Werror
main.c: In function ‘main’:
main.c:9:5: error: ignoring return value of ‘foo’, declared with attribute warn_unused_result [-Werror=unused-result]
    9 |     foo();
      |     ^~~~~
cc1: all warnings being treated as errors

如果您希望所有其他警告都只是警告,请使用进行编译-Werror=unused-result。例:

$ cat main.c 
__attribute__ ((warn_unused_result))
int foo (void)
{
    return 5;
}

int main(void)
{
    int *x = 5;
    foo();
}

$ gcc main.c -Werror=unused-result
main.c: In function ‘main’:
main.c:9:14: warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
    9 |     int *x = 5;
      |              ^
main.c:10:5: error: ignoring return value of ‘foo’, declared with attribute warn_unused_result [-Werror=unused-result]
   10 |     foo();
      |     ^~~~~
cc1: some warnings being treated as errors

更改签名以包括输出参数

完成类似操作的一种方法是将返回值移至参数。这将强制将“返回值”保存到参数,并且您必须在不向其发送输出变量的情况下调用该函数。更改

int fun (){ return 3;} 

void fun(int *ret) { *ret=3; }

但是如上所述,我看不到如何强制对变量进行适当的检查。这仅强制执行任务。

包装功能

另一种选择是使用包装器功能。这通常会大大降低灵活性,因此在使用它之前请三思而后行,但这是一种在某些情况下可能有用的选项。假设您有一个标头/源对。将包装器的原型放入头文件中,并将包装器和函数的实现放入源文件中。这将对程序员隐藏原始功能。它看起来可能像这样:

。H

int fun_wrapper();

。C

int fun() { return 3; }

int fun_wrapper() 
{ 
    int ret = fun(); 
    if(ret<0) exit(EXIT_FAILURE);
    return ret;
}

如何将此技术用于库函数

我创建了一个具有答案的相关问题。它是关于如何将此fgets功能用于库中的以及其他功能的:如何为具有原始名称的库函数创建包装器?


推荐阅读
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 本章将深入探讨移动 UI 设计的核心原则,帮助开发者构建简洁、高效且用户友好的界面。通过学习设计规则和用户体验优化技巧,您将能够创建出既美观又实用的移动应用。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 自学编程与计算机专业背景者的差异分析
    本文探讨了自学编程者和计算机专业毕业生在技能、知识结构及职业发展上的不同之处,结合实际案例分析两者的优势与劣势。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 阅读本文大约需要3分钟。微信8.0版本的发布带来了许多令人振奋的新功能,如烟花特效和改进的悬浮窗,引发了用户的热烈反响。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 作为一名程序员,从大学步入职场后,常常感受到一种难以言喻的空虚感。这种感觉或许源于对生活的不满、职业发展的瓶颈,或是日常琐事带来的压力。本文将深入探讨这种复杂的情感,并尝试寻找解决之道。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文深入探讨了C++对象模型中的一些细节问题,特别是虚拟继承和析构函数的处理。通过具体代码示例和详细分析,揭示了书中某些观点的不足之处,并提供了更合理的解释。 ... [详细]
  • 随着网络安全威胁的不断演变,电子邮件系统成为攻击者频繁利用的目标。本文详细探讨了电子邮件系统中的常见漏洞及其潜在风险,并提供了专业的防护建议。 ... [详细]
  • 微软Exchange服务器遭遇2022年版“千年虫”漏洞
    微软Exchange服务器在新年伊始遭遇了一个类似于‘千年虫’的日期处理漏洞,导致邮件传输受阻。该问题主要影响配置了FIP-FS恶意软件引擎的Exchange 2016和2019版本。 ... [详细]
author-avatar
过客松鼠_230
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有