【问题标题】:'=' should initialize either all enum members or only the first;'=' 应该初始化所有枚举成员或只初始化第一个;
【发布时间】:2014-01-16 16:54:28
【问题描述】:

我正在尝试使用以下枚举值构建我的代码:

typedef enum {           
    YUV_420P=0,    
    YUV_422P,         
    RGB_P,       
    BAYER_P,      
    YUV_422IBE,     
    YUV_444IBE,       
    A_1BIT,                  
    YUV_420SP,          
    COMPLEX_8BIT,             
    COMPLEX_16BIT,            
    COMPLEX_32BIT,        
    COMPLEX_U8BIT,           
    COMPLEX_U16BIT,            
    COMPLEX_U32BIT,                                   
    ALPHA_TYPE=0x8000                  
} Format;            

但在构建过程中,我收到以下棉绒警告..

sample.h: Note 960: Violates MISRA 2004 Required Rule 9.3, '=' should initialize either all enum members or only the first; enumerator: 'ALPHA_TYPE' ..  

我不想改变 ALPHA_TYPE 的值,我只想把 ALPHA_TYPE 放在这个枚举中。我该如何解决这个问题?

【问题讨论】:

  • 您需要符合 MISRA 编码标准吗?如果没有,你可以忽略这个。
  • 您并没有调用可怕的未定义行为,并且通常指定第一个元素的整数值,并理解其余元素将依次跟随。除非警告符合您的要求,否则请忽略它。
  • 即使对于激进的静态分析来说,这也是一个相当奇怪的要求。也许 MISRA 不了解枚举器是什么。
  • @Lightness MISRA 以安全的名义强加了很多无意义的规则;必须写if(var != 0) {} 而不是if(var) {} 除非var_Bool,这是我想到的。 Ashwin:与 MISRA 警告相比,该代码存在更大的问题,1BIT 不是有效标识符。

标签: c++ enums lint


【解决方案1】:

您的代码已经完成了您想要的工作。您只需要取消此特定警告即可。

另一方面,如果您确实需要遵守 MISRA 2004 规则 9.3,那么您将需要更改代码并找到不同的解决方案。但你不能两全其美。

【讨论】:

  • 忽略一个警告是不好的(最后你会得到很多并错过严重的警告) - 修复代码或使警告静音(如果你认为它一般无用)
  • @DieterLücking 你的建议和我一模一样!使警告静音。我当然不是建议忽略所有编译器警告。在这种情况下,只要开发人员决定可以将其静音,就只是这个非编译器警告。
  • @DieterLücking 的建议很聪明。如果您只是“忽略”警告,那么最终列表会变得如此之大,以至于您会错过重要的警告。如果可能,请使特定的静音,或者如果您不需要 MISRA,请静音 MISRA 警告。 ...或向日志文件发送警告并 grep 以自动过滤掉不需要的内容,保留有用的内容。
  • @DavidO 我同意。我没有其他建议。
【解决方案2】:

如果其他枚举的值无关紧要,你可以这样做

typedef enum {           
    ALPHA_TYPE=0x8000,                  
    YUV_420P,    
    YUV_422P,         
    RGB_P,       
    BAYER_P,      
    YUV_422IBE,     
    YUV_444IBE,       
    1BIT,                  
    YUV_420SP,          
    COMPLEX_8BIT,             
    COMPLEX_16BIT,            
    COMPLEX_32BIT,        
    COMPLEX_U8BIT,           
    COMPLEX_U16BIT,            
    COMPLEX_U32BIT                                   
} Format; 

或者

像这样定义你的所有枚举值(如果你添加一个新的枚举值,这样可以避免你的枚举值之一发生变化)

  typedef enum {                           
    YUV_420P=0,    
    YUV_422P=1,         
    RGB_P=2,       
    BAYER_P=3,      
    YUV_422IBE=4,     
    YUV_444IBE=5,       
    1BIT=6,                  
    YUV_420SP=7,          
    COMPLEX_8BIT=8,             
    COMPLEX_16BIT=9,            
    COMPLEX_32BIT=10,        
    COMPLEX_U8BIT=11,           
    COMPLEX_U16BIT=12,            
    COMPLEX_U32BIT=13,
    ALPHA_TYPE=0x8000                                   
} Format; 

【讨论】:

  • 这极大地改变了其他名称的值,例如使范围检查更加困难。
  • 而且由于您不知道枚举在其余代码中是如何使用的,因此您不知道这些值是否重要。
  • 因为 misra 9.3 规则语句类似于 :9.3 (req) 在枚举数列表中,“=”构造不应用于显式初始化除第一个以外的成员,除非所有项目都显式初始化。
【解决方案3】:

这当然不是 C++ 要求。

[C++11: 7.2/2]: 带有=enumerator-definition 为关联的枚举器提供了由constant-expression 指示的值。如果第一个枚举器没有初始化器,则相应常量的值为零。没有初始化器的 enumerator-definition 为枚举器提供通过增加前一个枚举器的值而获得的值 减一。

上面的语法允许多个枚举器有一个初始化器。

如果您被允许,也许您可​​以关闭检查是否符合“MISRA 2004”规则。你也可以简单地忽略它,因为它似乎只是一个Note。就个人而言,我会有点恼火一直弹出这个,但也许这只是我。

【讨论】:

    【解决方案4】:

    由于第一个枚举值是0,而且默认也是,所以直接使用默认即可。 ← 我看错了警告,这点不是解决办法.

    和/或,关闭 MISRA 规则检查。

    和/或,忽略特定注释。显然你可以通过+esym 选项来做到这一点。或者-esym,只是尝试一下并查看文档。

    【讨论】:

    • -1:删除第一个枚举器的初始化程序将如何解决这个问题?最后一个的初始化器仍然会触发这个条件。
    • @LightnessRacesinOrbit:谢谢,我误读了注释/警告,将“或仅第一个”(这对我没有意义)读作“或仅最后一个”(非常有意义,使用最后一个作为最大值是一种常见的习惯用法,使用倒数第二个初始化)
    • 确实如此。即使是激进的静态分析器也会抱怨,这有点奇怪。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 2017-08-16
    • 2019-09-10
    • 1970-01-01
    相关资源
    最近更新 更多