When should I use type abstraction in embedded systems
我已经研究了许多不同的嵌入式系统。它们都已将 这是一项很好的技术,因为它可以将类型的大小传递给程序员,并使您更加意识到溢出等的机会。 但是在某些系统上,您知道编译器和处理器在项目生命周期内不会改变。 那么,什么因素会影响您创建和实施项目特定类型的决定?
编辑 对于嵌入式编程,您可能需要特定大小的接口类型,并且还需要处理有限的资源(例如RAM)。这是不可避免的,但是您可以选择使用编译器中的基本类型。
对于其他所有类型,重要性都较小。 所以我认为我的问题应该是: 考虑到嵌入式软件的局限性,为有很多人在从事该项目的项目设置最好的策略是-并非所有人都有相同的经验水平。 我很少使用类型抽象。这是我的论点,按主观性从高到低排序:
局部变量在您希望它们适合寄存器的意义上不同于结构成员和数组。在32b / 64b目标上,本地
喜欢这些typedef的组织几乎总是以其中几个结尾(
从理论上讲,typedef可以帮助实现可移植性,但是我从来没有从中获得任何帮助。有没有一种有用的系统可以将32b目标移植到16b目标?有没有移植到32b目标的简单16b系统?此外,如果大多数var是整数,则实际上您将从新目标的32位中获得一些收益,但是如果它们是
现在,如果可移植性可能是typedef的理论上的好处,那么可读性肯定会付诸东流。只需查看stdint.h:
当然,在C ++中,通过使用重载的运算符和内容将数字包装在模板类实例中,可以使类型系统更加严格。这意味着您现在将收到以下格式的错误消息:"类Number
C99标准具有许多标准的大小整数类型。如果可以使用支持C99的编译器(gcc可以),则可以在
同样,在嵌入式项目中使用类型作为单位转换之类的"安全网"尤其重要。如果可以使用C ++,我知道那里有一些"单元"库,可以让您在由C ++类型系统(通过模板)定义的物理单元中工作,这些物理单元被编译为对基础标量类型的操作。例如,这些库不允许您将
即使您不能使用C ++或其他可以通过这种方式编写代码的语言,也可以至少使用C型系统来帮助您发现此类错误。 (这实际上是Simonyi匈牙利表示法的初衷。)仅仅因为编译器不会为向 我喜欢使用stdint.h类型来定义系统API,这是因为它们明确指出了大项目。在Palm OS的旧时代,系统API是使用一堆从非常经典的Mac OS继承来的" Word"和" SWord"类型定义的。他们做了一个清理工作,而不是说Int16,这使新手更容易理解API,特别是在该系统上出现16位指针异常的情况下。在设计Palm OS Cobalt时,他们再次更改了这些名称以匹配stdint.h的名称,从而使其更加清晰,并减少了他们必须管理的typedef数量。
我的意见是,如果您取决于最小/最大/特定大小,则不要仅假设 我相信MISRA标准建议(要求?)使用typedef。 从个人角度来看,使用typedefs不会对某些类型的大小(以位/字节为单位)造成混淆。我已经看到领先的开发人员尝试通过使用标准类型(例如int并使用自定义类型,例如UINT32。 如果代码不是可移植的,则使用typedef几乎没有真正的好处,但是,如果像我一样,您同时使用两种类型的软件(便携式和固定环境),则保持标准并使用定制的类型可能很有用。至少像您说的那样,程序员然后非常了解他们正在使用多少内存。要考虑的另一个因素是您如何"确定"代码不会移植到另一个环境?我见过必须翻译处理器特定的代码,因为硬件工程师突然不得不更换一块板子,这不是一个很好的情况,但是由于自定义typedef,情况可能会更糟!
使用
当您对所有内容进行测试时,它可能会非常咬人,但由于 如果您的嵌入式系统在某种程度上是安全性至关重要的系统(或类似系统),则强烈建议(如果不需要)在普通类型上使用typedef。 作为传统知识。之前已经说过,MISRA-C有一个(建议)规则可以这样做:
(摘自MISRA-C 2004;这是MISRA-C 1998的规则13(adv)) 这在这方面也适用于C ++。例如。 JSF C ++编码标准:
一致性,方便性和可读性。" UINT32"比" unsigned long long"更具可读性和可写性,这在某些系统中是等效的。 同样,在项目的整个生命周期中,编译器和处理器可能是固定的,但是该项目中的代码可能会在另一个项目中找到新的生命。在这种情况下,具有一致的数据类型非常方便。 也许我很奇怪,但是我将ub,ui,ul,sb,si和sl用于整数类型。也许16位的" i"似乎有些陈旧,但是我更喜欢ui / si的外观而不是uw / sw。 |