gpt4 book ai didi

c++ - 如何防止从某些代码段调用函数?

转载 作者:太空宇宙 更新时间:2023-11-04 06:52:56 26 4
gpt4 key购买 nike

我正在实现一个辅助类,它有许多有用的函数,这些函数将在大量类中使用。但是,它们中的一些并不是设计为从某些代码段中调用的(从中断函数,这是一个嵌入式项目)。

然而,对于此类的用户来说,为什么某些函数被允许而其他函数被禁止从中断函数中调用的原因可能不是很明显,在许多情况下,被禁止的函数可能会起作用,但会导致非常微妙和难以稍后发现错误。

对我来说最好的解决方案是,如果从不应该从中调用的代码部分调用有问题的函数,则导致编译器错误。

我也考虑过一些非技术解决方案,但首选技术解决方案。

  1. 在文档中用警告说明。可能很容易被遗漏,尤其是当函数看起来很明显时,比如 read_byte(),为什么有人要研究文档是否函数是可重入的?

  2. 在函数名中注明。丑陋的。谁喜欢像 read_byte_DO_NOT_CALL_FROM_INTERRUPT() 这样的函数名称?

  3. 在每个文件中包含的公共(public) header 中有一个全局变量,在每个中断开始时设置为 true,在结束时设置为 false,违规函数在开始时检查它, 如果已设置则退出。问题:中断可能会相互中断。此外,它不会导致编译时警告或错误。

  4. 与 #3 类似,拥有一个带堆栈的全局处理程序,以便可以处理嵌套中断。仍然存在仅在运行时工作的问题,并且还增加了很多开销。中断不应为此功能浪费超过一两个时钟周期(如果有的话)。

  5. 滥用预处理器。不幸的是,在每个中断开始时使用 #define 并在结束时使用 #undef 的天真方式,在中断处使用 #ifdef有问题的函数的开头不起作用,因为预处理器不关心范围。

  6. 由于中断始终是无类函数,我可以将有问题的函数设为protected,并在所有使用它们的类中将它们声明为friends。这样,就不可能直接在中断中使用它们。由于 main() 是无类的,我必须将其大部分放入类方法中。我不太喜欢这个,因为它会变得不必要的复杂,而且它产生的错误并不明显(所以这个函数的用户可能会封装它们来“解决”问题,而没有意识到真正的 问题是)。像“错误:function_name() 不在中断中使用” 这样的编译器或链接器错误消息会更可取。

  7. 检查函数内的中断寄存器有几个问题。在大型微 Controller 中,有很多寄存器需要检查。此外,当中断标志正好在一个时钟周期之前被设置时,误报的可能性非常小但很危险,所以我的函数会失败,因为它认为它是从中断中调用的,而中断将在下一个周期。此外,在嵌套中断中,中断标志被清除,导致漏报。最后,这是另一个运行时解决方案。

我不久前确实玩过一些非常基本的模板元编程,但我没有找到非常简单和优雅的解决方案的经验。在致力于实现模板元编程过时软件之前,我宁愿尝试其他方法。

仅使用 C 中可用功能的解决方案也是可以接受的,甚至更可取。

最佳答案

下面是一些评论。作为警告,它们阅读起来不会很有趣,但我不会不指出这里的问题来为您服务。

  • 如果您从 ISR 内部调用外部函数,再多的文档或编码也无济于事。因为在大多数情况下,这样做是不好的做法。程序员必须知道他们在做什么,否则再多的文档或编码机制也无法挽救程序。

    程序员不会专门为从 ISR 内部调用而设计库函数。相反,程序员在设计 ISR 时考虑到 ISR 附带的所有特殊限制:确保中断标志被正确清除,保持代码简短,不要调用外部函数,不要阻塞 MCU 超过必要的时间,考虑重新-entrancy,考虑危险的编译器优化(使用 volatile)。不知道这一点的人没有足够的能力编写 ISR。

  • 如果您实际上有一个函数 int read_byte(int address) 那么这表明程序设计一开始就很糟糕。这个函数可以做两件事之一:

    • 要么它可以读取一些外围硬件的一个字节,在这种情况下,函数名称非常糟糕,应该更改。
    • 或者它可以从地址读取任何通用字节,在这种情况下,该函数是 100% 无用的“膨胀软件”。您可以安全地假设一个有点能力的 C 程序员可以从内存地址读取一个字节,而无需一些英国媒体报道软件。

    无论哪种情况,int 都不是字节。它是一个 16 位或 32 位的字。该函数应返回 uint8_t。同样,如果传递的参数用于描述 MCU 的内存映射地址,则它的类型应该是 void*uint8_t*uintptr_t。其他一切都是错误的。

    值得注意的是,如果您使用 int 而不是 stdint.h 进行嵌入式系统编程,那么整个讨论是您遇到的最少的问题,因为您还没有甚至正确掌握了基本知识。您的程序将充满未定义的行为和隐式提升错误。

总的来说,您提出的所有解决方案都是 Not Acceptable 。这里问题的根源似乎是程序设计。解决这个问题,而不是发明使用可怕的元编程来保护损坏的设计的方法。

关于c++ - 如何防止从某些代码段调用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48620223/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com