Start here

Home
About Klocwork
What's new
Fixed issues
Release notes
Installation

Reference

C/C++ checkers
Java checkers
C# checkers
MISRA C 2004 checkers
MISRA C++ 2008 checkers
MISRA C 2012 checkers
MISRA C 2012 checkers with Amendment 1
Commands
Metrics
Troubleshooting
Reference

Product components

C/C++ Integration build analysis
Java Integration build analysis
Desktop analysis
Refactoring
Klocwork Static Code Analysis
Klocwork Code Review
Structure101
Tuning
Custom checkers

Coding environments

Visual Studio
Eclipse for C/C++
Eclipse for Java
IntelliJ IDEA
Other

Administration

Project configuration
Build configuration
Administration
Analysis performance
Server performance
Security/permissions
Licensing
Klocwork Static Code Analysis Web API
Klocwork Code Review Web API

Community

View help online
Visit RogueWave.com
Klocwork Support
Rogue Wave Videos

Legal

Legal information

MISRA.BUILTIN_NUMERIC

Builtin numeric type is used.

MISRA C 2012 Dir 4.6 typedefs that indicate size and signedness should be used in place of the basic numerical types

Category: Advisory

Applies to: C90, C99

Amplification

The basic numerical types of char, short, int, long, long long (C99), float, double and long double should not be used, but specific-length typedefs should be used.

For C99, the types provided by <stdint.h> should be used. For C90, equivalent types should be defined and used.

A type must not be defined with a specific length unless the implemented type is actually of that length.

It is not necessary to use typedefs in the declaration of bit-fields.

typedef signed   char   int8_t; 
typedef signed   short  int16_t; 
typedef signed   int    int32_t;
typedef signed   long   int64_t;

typedef unsigned char   uint8_t; 
typedef unsigned short  uint16_t; 
typedef unsigned int    uint32_t; 
typedef unsigned long   uint64_t;

typedef          float  float32_t; 
typedef          double float64_t; 
typedef long     double float128_t;

Rationale

In situations where the amount of memory being allocated is important, using specific-length types makes it clear how much storage is being reserved for each object.

Adherence to this guideline does not guarantee portability because the size of the int type may determine whether or not an expression is subject to integer promotion. For example, an expression with type int16_t will not be promoted if int is implemented using 16 bits but will be promoted if int is implemented using 32 bits. This is discussed in more detail in the section on integer promotion in Appendix C.

Note: defining a specific-length type whose size is not the same as the implemented type is counter- productive both in terms of storage requirements and in terms of portability. Care should be taken to avoid defining types with the wrong size.

If abstract types are defined in terms of a specific-length type then it is not necessary, and may even be undesirable, for those abstract types to specify the size or sign. For example, the following code defines an abstract type representing mass in kilograms but does not indicate its size or sign:

typedef uint16_t mass_kg_t;

It might be desirable not to apply this guideline when interfacing with The Standard Library or code outside the project’s control.

Exception

  1. The basic numerical types may be used in a typedef to define a specific-length type.
  2. For function main, an int may be used rather than the typedefs as a return type. Therefore int main (void) is permitted.
  3. For function main an int may be used rather than the typedefs for the input parameter argc.
  4. For function main a char may be used rather than the typedefs for the input parameter argv.

Therefore int main( int argc, char *argv[] ) is permitted (C99 Section 5.1.2.2.1).

Example

/* Non-compliant - int used to define an object        */ 
int x = 0;

/* Compliant - int used to define specific-length type */ 
typedef int SINT_16;

/* Non-compliant - no sign or size specified           */ 
typedef int speed_t;

/* Compliant - further abstraction does not need specific length */ 
typedef int16_t torque_t;

MISRA-C 2004 Rule 6.3 (advisory): typedefs that indicate size and signedness should be used in place of the basic numerical types

Built-in numeric type is used.

The basic numerical types of signed and unsigned variants of char, int, short, long and float, double should not be used, but specific-length typedefs should be used. Rule 6.3 helps to clarify the size of the storage, but does not guarantee portability because of the asymmetric behaviour of integral promotion. See discussion of integral promotion — section 6.10. It is still important to understand the integer size of the implementation.

Programmers should be aware of the actual implementation of the typedefs under these definitions.

For example, the ISO (POSIX) typedefs as shown below are recommended and are used for all basic numerical and character types in this document. For a 32-bit integer machine, these are as follows:

Example

typedef          char   char_t;
typedef signed   char   int8_t;
typedef signed   short  int16_t;
typedef signed   int    int32_t;
typedef signed   long   int64_t;
typedef unsigned char   uint8_t;
typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;
typedef unsigned long   uint64_t;
typedef          float  float32_t;
typedef          double float64_t;
typedef long     double float128_t;

typedefs are not considered necessary in the specification of bit-field types.

MISRA-C++ 2008 Rule 3-9-2 (advisory): typedefs that indicate size and signedness should be used in place of the basic numerical types.

[Implementation 3.9.1(1, 5)]

Rationale

The basic numerical types of char, int, short, long, float, double and long double should not be used, but specific-length typedefs should be used. This rule helps to clarify the size of the storage, but does not guarantee portability because of the asymmetric behaviour of integral promotion. See the discussion of integral promotion in Section 6.5.0. It is still important to understand the integer size of the implementation. Developers should be aware of the actual implementation of the typedefs under these definitions.

Exception

The wchar_t does not need a typedef as it always maps to a type that supports wide characters. The char_t typedef does not indicate size and signedness and is simply included to allow char objects to be declared without the use of the basic char type, allowing any use of (plain) char to be detected and reported by analysis tools.

Example

The ISO (POSIX) typedefs as shown below are recommended and are used for all basic numerical and character types in this document. For a 32-bit integer machine, these are as follows:

typedef          char   char_t;
typedef signed   char   int8_t;
typedef signed   short  int16_t;
typedef signed   int    int32_t;
typedef signed   long   int64_t;
typedef unsigned char   uint8_t;
typedef unsigned short  uint16_t;
typedef unsigned int    uint32_t;
typedef unsigned long   uint64_t;
typedef          float  float32_t;
typedef          double float64_t;
typedef long     double float128_t;

typedefs are not considered necessary in the specification of bit-field types.