This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器:TI ARM 编译器20.x、stdins 和 C99中支持的 Misra

Guru**** 2524460 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/926273/compiler-misra-as-supported-in-ti-arm-compiler-20-x-and-stdints-and-c99

工具/软件:TI C/C++编译器

编译器附带 MISRA C 2004检查支持。  例如、MISRA 版本不支持 C99。

但是、我似乎包括了它  那么我不会收到任何警告。  或者该标头是否与所提供的完全 MISRA 兼容? 如果我在此  模块上设置了严格的 ANSI C89 (只是检查)、我似乎也没有收到任何警告、但它仍然可以正常构建。

我在 stdint.h 标题中看到这些内容:

#include <_ti_config.h>

_TI_OPERTI_pragma ("diag_push")
_TI_OPERTI_pragma ("check_MISRA (\""-19.1\"")")/*#include 之前没有代码*/
_TI_OPERTI_pragma ("check_MISRA (\""-19.7\"")))/*更喜欢宏函数*

不知道这些专有宏意味着什么、但 提供的 stdint.h (及其包含的内容)是否完全符合 MISRA 标准?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [报价用户="v01d"]提供的标题是否与 MISRA 完全兼容?

    是的

    [引用 user="v01d"]不知道这些专有宏的含义

    这些宏会抑制某些否则会发出的 MISRA 诊断。  每一项审查都是经过审查的,并被判定不是违反行为。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    该标头似乎不完全符合该 MISRA。

    #include 
    
    uint8_t tmp;
    
    tmp = uint8_MAX;
    
    

    我得到的 MISRA 警告/错误:  

    说明资源路径位置类型
    #1393-D (MISRA-C:2004 10.1/R)整数类型表达式的值如果不转换为相同符号的更宽整数类型,则不应隐式转换为不同的基础类型.  C/C++问题

    但是,这不是:

    tmp = 0xffffff; 

    因此、该报头可能未完全打开 MISRA 校验器。

    TI 是否有任何计划即将支持 MISRA >= 2012?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您将此问题通知我们、并提供了一个简洁的测试案例。  我可以重现相同的行为。  我提交了 EXT_EP-9939条目 以进行调查。  欢迎您使用我签名中的以下链接进行操作。

    [报价用户="v01d"] TI 是否有任何计划 即将支持 MISRA >= 2012?

    遗憾的是、没有计划向 TI 编译器添加对 MISRA 2012的支持。  我们建议您使用其他静态代码分析工具来获得解决方案。

    谢谢、此致、

    乔治   

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    令人困惑的是、uint8_MAX 的类型不是 uint8_t

    C99 7.18。 "limits of specified-width integer types"(指定宽度整数类型的限制)指出:"此表达式应具有与根据整数升级转换的对应类型对象的表达式相同的类型。" 因此、此宏具有类型为"signed int"的值、您会收到一条 MISRA-2004警告、提示您尝试将其直接分配给类型为 uint8_t 的变量

    另一方面、MISRA-2004有一个常量的特殊情况。 MISRA-2004特别允许您使用第二个案例"tmp = 0xxu"、因为它是一个字面常量、其值适合 x 而不更改值。  MISRA-2004不会对具有合适值的宏进行例外处理、也不会将 UINT8_MAX 识别为特殊情况、因为它是 C99功能。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="archaeology"]

    令人困惑的是、uint8_MAX 的类型不是 uint8_t

    [/报价]

    从 TI 编译器随附的 stdint.h 头文件中可以清楚地看出、它是一个定义、是一个字面量 int (现在不要在我的头文件中包含它、但它甚至是定义为无符号的、还是只定义为 int。)

    [引用 user="archaeology"]它也不会将 UINT8_MAX 识别为特殊情况,因为它是 C99功能。

    我理解、但我认为随编译器提供的标头允许使用它、以便与附带的 MISRA 2004检查器兼容。

    我不想长时间停留在2004 MISRA 中、但 ATM 这是编译器提供的免费检查器。 我还看到/看到设置严格 ANSI 模式并不排除 ME 或将此标记为错误,以便将 stdint.h 包括在代码中,即使使用标准 C89也是如此。 我认为这意味着此编译器和 MISRA 校验器在89或99中接受该标头完全兼容且可用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    对于 ARM、C99标准要求 uint8_MAX 为有符号整型、因为 uint8_t 小于"int"、并且将整数提升为"int"。  对于 ARM 20.x、UINT8_MAX 定义为令牌0xff、这是一个非后缀的十六进制常量、因此未在源代码中指定类型。  这意味着编译器需要根据标准中的规则(C99 6.4.4.1 "整数常量")推断类型、而对于 ARM、这实际上是一个需要的有符号整型。

    MISRA-C:2004预计输入将在"严格 ANSI"模式下编译、实现过程中要检查的一点是您使用了"严格 ANSI"编译器选项。  如果没有选项、这并不意味着要使用它、尽管如果没有选项、它通常可以正常工作。

    TI 编译器的"严格 ANSI"模式并不意味着它只接受标准代码;它意味着编译器将禁用会干扰对严格符合标准的程序的解释的扩展。  这需要一些解释。  C 标准将"严格符合"程序定义为仅使用 C 标准中定义的那些功能的程序、不依赖于任何实现(编译器)定义的行为。  C 标准将"符合性实施"定义为接受所有严格符合性计划的实施。  如果编译器在其默认模式下不接受所有严格符合标准的程序、则没关系、它只需要接受所有此类程序的模式。   "严格 ANSI"模式就是该模式。  例如、关键字"inline"是 C89程序中的一个完全有效的标识符、但如果您尝试在默认模式下将其用作变量名称、则会出现语法错误。  通过使用"严格 ANSI"模式、您可以禁用"内联"作为关键字、现在您可以编译一个使用"内联"作为变量名称的严格符合规范的程序。

    现在、stdbool.h 不是 C89功能、因此使用它的程序不是严格遵循规范的 C89程序。  该程序可能是严格符合规范的 C99程序、但这对 MISRA-C:2004无关紧要;它期望编译器处于"符合"(也称为"严格 ANSI") C89模式。  因此、使用 stdbool.h 的程序不属于 MISRA-C:2004的范围。  现在、仅包括 stdbool.h 是相当无害的、因此我们已向 stdbool.h 添加了 pragma、以禁用文件本身内部的几个 MISRA-C:2004检查、以便您至少可以包含该文件。  但是、这些 pragma 不会扩展到使用 stdbool.h 中定义的代码  不应将这些 pragma 的存在视为在打算使用 MISRA-C:2004检查的程序中支持使用 stdbool.h;它们只是对想要稍微放宽 MISRA-C:2004规则的程序来说很方便。  包括 stdbool.h 将使您的程序不可移植到仅 C89的实现、可移植性是 MISRA-C:2004的主要问题之一。

    总之、您可以包含 stdbool.h、而不会从 MISRA-C:2004中收到任何警告、但它会使您的程序的可移植性稍微降低、并且当您尝试使用头文件中的定义时、您仍然可能会收到 MISRA-C:2004警告。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="archaeology">现在、stdbool.h 不是 C89功能、因此使用该功能的程序不是严格符合要求的 C89程序。  该程序可能是严格符合规范的 C99程序、但这对 MISRA-C:2004无关紧要;它 e

    我想这是针对我的另一个线程。

    了解有关使用标准 C 和 ARM 的整数升级规则的所有信息-谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我会诚实地说、我发现这不是直接理解的:

    [引用 user="archaeology">TI 编译器的"严格 ANSI"模式并不意味着它只接受标准代码;它意味着编译器将禁用会干扰对严格符合标准的程序的解释的扩展。  这需要一些解释。  C 标准将"严格符合"程序定义为仅使用 C 标准中定义的那些功能的程序、不依赖于任何实现(编译器)定义的行为。  C 标准将"符合性实施"定义为接受所有严格符合性计划的实施。  如果编译器在其默认模式下不接受所有严格符合标准的程序、则没关系、它只需要接受所有此类程序的模式。   "严格 ANSI"模式就是该模式。  例如、关键字"inline"是 C89程序中的一个完全有效的标识符、但如果您尝试在默认模式下将其用作变量名称、则会出现语法错误。  通过使用"严格 ANSI"模式、可以禁用"内联"作为关键字、现在可以编译使用"内联"作为变量名称的严格符合规范的程序。[/quot]

    我特别想问一下:

    [引用 user="archaeology">如果编译器在其默认模式下不接受所有严格符合标准的程序、则该编译器只需要接受所有此类程序的模式。   "严格 ANSI"模式就是该模式。  [/报价]

    我是否理解错误、但这是否意味着"默认'mode"(对于此编译器) 是一种更严格/有限的模式、它甚至不接受所有符合标准的模式?  而"严格 ANSI"模式更容易接受?   即,此处为“严格 ANSI”> “默认”模式? 我本来希望它会反向 -完全符合 ANSI 模式是更严格的< 默认 的编译器模式、可能具有提供程序扩展。

    在这里:  

    [引用 user="archaeology"] TI 编译器的"严格 ANSI/"模式并不意味着它只接受标准代码;它意味着编译器将禁用会干扰对严格符合标准的程序的解释的扩展。

    &&

    例如、

    archaeology 说:
    关键字"inline"是 C89程序中完全有效的标识符、但如果您尝试在默认模式下将其用作变量名称、则会出现语法错误。  通过使用"严格 ANSI"模式、可以禁用"内联"作为关键字、现在可以编译使用"内联"作为变量名称的严格符合规范的程序。[/quot]

    我是否也理解错了: 这里的"ANSI"是否意味着旧 的 C89 (或 C90),并且 不对应于标准的特定修订版(例如 C99)的第二个选项/标志?   (我认为 ANSI 也采用了此及更高版本的标准)

    因此,对于 inline 关键字示例:  我希望,设置 选项 标准= C99 &&严格 ANSI 将允许我使用关键字'inline'(我认为是 C99的一部分)。   ,但 如果标准 < C99 && 严格 ANSI ,则会根据您的示例禁用内联。

    但是,从您的解释中我似乎得到了什么,TI 的 ANSI 只知道标准的第一个版本?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请在 TI ARM 编译器手册中搜索 标题为 严格 ANSI 模式和宽松 ANSI 模式的子章节。  您是否更好地理解了这种解释?

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     :

    5.16.3、p 132

    "。  

    在宽松 ANSI/ISO 模式(默认)下、编译器接受可能的语言扩展
    可能与严格符合 ANSI/ISO C/C++程序相冲突。 在严格 ANSI 模式下、这些
    语言扩展被抑制、这样编译器将接受所有严格遵循规范的程序。
    当您知道您的程序是符合标准的程序并且不会进行编译时、请使用-strict_ansi 选项
    在宽松模式下。 在此模式下、会禁用与 ANSI/ISO C/C++冲突的语言扩展并
    编译器将在标准要求它这样做的情况下发出错误消息。 违反行为
    标准认为可酌情决定、但可以作为警告发出。 "

    这似乎 -至少在我的阅读中-完全符合我的预期/理解它的工作。  我无法与上面给出的解释结婚。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    让我再试一次。  首先、"严格 ANSI"模式和选项是模式的一个较差名称;遗憾的是、我们现在一直坚持使用它。  这种模式实际上应该被称为"符合模式"。  这是保证接受所有严格符合要求的程序的模式。  严格符合标准的程序是一个狭窄的类别;它经过仔细编写、因此不使用 C 标准中没有的任何功能、也不依赖于实施定义的行为、例如"int"的大小。  每个语言版本都有不同的"严格 ANSI"模式、因此有一个"严格 ANSI C89、"严格 ANSI C99、"严格 ANSI C++98等。

    大多数程序在默认的"宽松"模式或"严格 ANSI/"模式下都可以接受。  只有少数方案将被一个或另一个方案拒绝。  这种程序的一个很好的例子是使用标识符"inline"作为变量名称。  就 C 标准而言、这是完全合法的、因此严格符合标准的 C 程序可以使用"inline"作为变量或函数名称。  但是、作为语言扩展、TI 编译器在默认模式下实现了"内联"作为关键字、以便您可以将其用于内联函数。  这意味着默认模式不接受使用"inline"作为变量名称的严格遵循规范的程序。  为了解决此问题、您将使用"严格 ANSI"模式、该模式会关闭与接受严格符合要求的程序冲突的扩展。

    实际程序通常需要"严格 ANSI"模式。  通常、允许所有可能的语言扩展更有用;也就是说、在默认模式下、我们更有可能接受任何特定的随机程序。  这就是它是默认值的原因。

    请注意、我们使用内联作为关键字内联函数的假设程序将在"严格 ANSI C89"模式下被拒绝、但会在"严格 ANSI C99"模式下被接受。

    那么、现在我们问、哪种模式更"限制?"  嗯、真的。  每个程序都接受少量程序、而另一个程序不接受这些程序。  "严格 ANSI"模式将接受严格遵循规范的 C89程序、该程序使用 INLINE 作为变量名称。  默认(宽松)模式将接受使用内联作为内联函数的关键字的不严格遵循规范的 C89程序。  在实践中、我会说更多的"现实世界"计划将在默认模式下被接受、这只是因为人们确实使用了语言扩展。  严格符合标准的程序不太常见、除非高度可移植性是一个大问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    @

    再次感谢您的详细解释。  我认为这更好地解释了您在上一个帖子中所解释的内容。默认模式与严格模式。 (还让我再次思考符合标准的是什么...)

    'inline'示例的注释:  对于'strict ANSI C99' 模式或默认/宽松模式,两者都将接受它并将其作为指令,  因此在这一个关键字示例中,我们遵循并具有"Read world"有用的关键字。   )