2047 incompatible redefinition of macro %nod
Cause:
A #define preprocessing directive has redefined a macro whose previous definition contained an error or warning. Normally, the compiler will issue a warning if a macro is redefined to something other than the previous definition. However, if the previous definition caused a warning or error to be generated, this informational message is output instead.
Example:
#define KM_SLEEP 0
#define KM_SLEEP 1
Action:
Do not redefine a macro without first undefining it.
Reference:
C99 6.9.3
2054 Too few arguments in macro invocation
Cause:
Some parameter/s is/are omitted during macro invocation.
Example:
#define FOO(a, b, c) (( a << 3 ) | b)
int a, b;
int main() {
(void) FOO(a, b);
}
Action:
Pass right number of parameters during macro invocation.
Reference:
2063 shift count is too large
Cause:
The compiler has detected a shift count that is greater than or equal to the size of the operand to be shifted. This may not be your intent, as the result contains none of the original bits of the operand.
Example:
int main() {
int a = 1 << 32;
}
Action:
Avoid using the shift count greater than number of bits a given type can hold.
Reference:
2064 declaration does not declare anything
Cause:
The declaration does not declare anything. The C standard requires that a declaration must declare at least a tag, an enumeration constant or a declarator.
Example:
int;
Action:
Correct or remove the declaration.
Reference:
C99 6.7.2, ANSI/ISO C++ 6.7(2)
2068 integer conversion resulted in a change of sign
Cause:
Conversion of integer resulted in sign change. Either an unsigned 1-bit bitfield was assigned -1, or a signed 1-bit bitfield was assigned 1.
Example:
#define NEGATIVE (-1)
int main() {
unsigned int a = NEGATIVE;
}
Action:
Conversion from a signed int to unsigned leads to change of sign. This might result in an unexpected
behavior of the
code. If the sign of the integer is not a concern, then this diagnostic can be ignored. Otherwise, do not assign a
signed value to unsigned type and vice versa.
Reference:
2069 integer conversion resulted in truncation
Cause:
Conversion of integer resulted in truncation. This causes loss of some digits.
Example:
#define FCD_NEGATIVE 390000000
int main() {
short int a = FCD_NEGATIVE;
}
Action:
Conversion from a larger integral type to a smaller integral type leads to truncation. This might result in an unexpected
behavior of the code. Hence, avoid doing such conversions.
Reference:
2102 forward declaration of enum type is nonstandard
Cause:
It is non standard to provide forward declarations for enumerations.
Example:
enum Consts;
Action:
Define the enumerations instead of forward declaration as:
enum Consts { MIN = 10, MAX = 100 };
Reference:
ANSI/ISO C++ 7.2(1)
2111 statement is unreachable
Cause:
Code at this location will never be executed. Often unreachable statements represent a real coding error such as a wrongly inserted return, goto, throw or call to non-returning functions etc.
Example:
return 0;
i++; // warning 2111 here
Action:
Check for incorrectly placed unconditional control transfer statements.
2128 loop is not reachable from preceding code
Cause:
A loop has been detected by the compiler which can never be reached.
Example:
int main() {
if (1)
return 0;
for(int a = 0; a < 3; a++) {
if (a == 1)
return 1;
}
}
Action:
If the loop is necessary, change the code such that the loop can be reached. Otherwise, remove the loop.
Reference:
2147 declaration is incompatible with %nfd
Cause:
The declaration or definition provided is incompatible with a previous declaration.
Example:
class Init {
static const float fmem;
};
float Init::fmem = 10.0f;
Action:
Check if given declaration/definition is consistent with the previous declaration. For example, the qualifiers might be missing, the type declared might be different etc. The given example can be corrected as follows:
class Init {
static const float fmem;
};
const float Init::fmem = 10.0f;
Reference:
2186 pointless comparison of unsigned integer with zero
Cause:
An unsigned expression is being tested to see if it is greater than zero. An ordered comparison between an unsigned value and a constant that is zero may indicate a programming error.
Example:
size_t i = 10;
if(i >= 0)
printf("true");
Action:
Cast (or otherwise rewrite) one of the operands of the compare to match the signedness of the other operand, or compare for equality with zero.
Reference:
2187 use of "=" where "==" may have been intended
Cause:
The assignment expression is used as the controlling expression of an if, while or for statement.A common user mistake is to accidentally use assignment operator "="instead of the equality operator "==" in an expression that controls a transfer.
For example saying if (a = b) instead of if (a == b).While using the assignment operator is valid, it is often not what is intended. When this message is enabled, the compiler will detect these cases at compile-time. This can often avoid long debugging sessions needed to find the bug in the user's program.
Example:
void check_ten(int arg) {
if(arg = 10)
printf("true");
}
Action:
Make sure that the assignment operator is what is expected.
Reference:
2191 type qualifier is meaningless on cast type
Cause:
Casting to a qualified type, though valid, is pointless. This is reported only when the cv-qualifiers are explicit in the cast,not, for example, when they are hidden in a typedef or template parameter type.
Example:
int i = (const volatile int) 10;
Action:
Remove the unnecessary qualifiers in the cast.
Reference:
2192 unrecognized character escape sequence
Cause:
An escape sequence consists of a '\' (backslash) character followed by one or more characters. This diagnostic is issued if the character following the '\' is not known or not recognized by the compiler.
Example:
printf("%c", '\z');
Action:
Check if the character provided after the '\' character is really a recognized escape sequence character.
Reference:
C99 5.2.1, 5.2.2
2226 invalid format string conversion
Cause:
The compiler has detected an ill formed conversion specification (flags, width, precision, length
modifier) or an unknown conversion specifier (not diouxefgcspn...) that will cause unpredictable behavior.
Example:
printf("%z ", 2);
Action:
Review the documentation for this function and modify the conversion specification as appropriate.
Reference:
2228 trailing comma is nonstandard
Cause:
Accepting an enumerator list that contains a trailing comma is an extension of HP C provided for compatibility
with other C compilers. An enumerator list with a trailing comma is not valid in C89, nor in C++.The C99 standard does permit this syntax.
Example:
typedef enum Switch {
on,
off,
} var;
Action:
Remove the trailing comma.
Reference: C99 6.7.2.2 ANSI/ISO C++ 7.2
2236 controlling expression is constant
Cause:
A boolean controlling expression tests for a constant pointer or pointer to member values.
NOTE: This warning is not issued for cases like if (1) ; since these often result from valid macro expansions.
Example:
void foo();
int main() {
if (foo) { // warning 2236 here.
}
}
}
Action:
A test of a constant address is unusual, and might be a done by mistake - check if this is what you intended.
Reference:
2252 reference %n requires an initializer
Cause:
Reference variables should always be initialized, unless the reference is declared as extern , or it is declared as a class member within a class declaration, or it is declared as a parameter or function return type.
Example:
int &ir;
}
Action:
Provide an initializer for the reference. For example:
int i;
int &ir = i;
Reference:
ANSI/ISO C++ 8.3.2 (4)
2260 explicit type is missing ("int" assumed)
Cause:
The declaration has a storage-class specifier,but no type was specified. The compiler will assume the type of int. Omitting the type specifier is not valid in C++ or in C99, and is often considered poor programming practice.
Example:
static i;
Action:
Add a type specifier to the declaration.
Reference:
C99 6.5.2.2, 6.7.2; C++ Section 7
2263 duplicate base class name
Cause:
The same base class name is specified more than once in the base class list. A base class name should appear only once in a base class list.
Example:
class Base {};
class Derived: public Base, protected Base {};
Action:
Remove the redundant base class name, for example:
class Derived: public Base {};
Reference:
2267 old-style parameter list (anachronism)
Cause:
The given function is defined using the old style K&R syntax. The C standard has marked this syntax as obsolescent,
and it is not supported in C++. Consider using the standard C prototype syntax.
Example:
int foo(arg)
int arg;
{ return arg; }
Action:
Recode the function definition to use the recommended prototype-format definition.
Reference:
C99 6.9.1
2269 conversion to inaccessible base class %t is not allowed
Cause:
It is incorrect to assign a derived object to a protected or private base class pointer or reference without an explicit cast.
NOTE: If an explicit access specifier is missing while inheriting from a base class then private inheritance is assumed. In case of inheriting from a struct public inheritance is assumed.
Example:
class Base {};
class Derived: protected Base{};
Base *b = new Derived;
Action:
Check if you actually want to convert from the derived to base type. If yes, then provide an explicit cast:
Base *b = (Base*) new Derived;
Reference:
ANSI/ISO C++ 8.3.2 (4)
2306 default argument not at end of parameter list
Cause:
Default arguments can only be provided at the end of the parameter list. All the parameters following a parameter with default argument must also have default arguments.
Example:
void print(int argc = 0, char **argv);
Action:
Remove the given default arguments, or provide default arguments to all the parameters following that parameter or rearrange the parameter list. For example:
void print(int argc, char **argv);
// or
void print(int argc = 0, char **argv = 0);
// or
void print(char **argv, int argc = 0);
Reference:
ANSI/ISO C++ 8.3.6 (4)
2314 only nonstatic member functions may be virtual
Cause:
Only non-static member functions can be declared as virtual, static members functions cannot be virtual.
Example:
class Base {
virtual static void vfoo() {}
};
Action:
Make the member function either static or virtual, for example:
virtual void vfoo() {}
Reference:
2315 the object has cv-qualifiers that are not compatible with the member function
Cause:
The cv qualifiers ( const and volatile qualifiers) of the object should be compatible with the cv qualifiers of member functions that it calls. For example, any attempt to call a non-const member function on a const object will result in an error.
Example:
int main() {
struct X {
void foo();
};
const X s;
s.foo();
}
Action:
Ensure that the cv qualifiers of the object are not stricter than cv qualifiers of the methods that called through it.
Reference:
ANSI/ISO C++ 9.3.2(4)
2319 pure specifier ("= 0") allowed only on virtual functions
Cause:
Only virtual functions can be declared as pure; other functions cannot have pure specifier as it is meaningless.
Example:
class base {
public:
static int foo() = 0;
};
Action:
Provide the pure specifier only for virtual functions.
Reference:
ANSI/ISO C++ 9.3.1(4)
2320 badly-formed pure specifier (only "= 0" is allowed)
Cause:
Pure virtual functions are declared by a pure specifier indicated by = 0 ; = 0 does not indicate initialization or assignment, hence 0 cannot be replaced by other values.
Example:
class base {
public:
virtual int foo() = 1;
};
Action:
Provide the pure specifier only as "= 0", for example:
virtual int foo() = 0;
Reference:
ANSI/ISO C++ 9.2, 10.4(2)
2321 data member initializer is not allowed
Cause:
Only static const members of integral or enumeration type can be initialized inline in a class definition. For other types, provide the initialization outside the class definition.
Example:
int i = 100;
class Init {
static const int *p_i = &i;
};
Action:
Initialize the member outside the class:
int i = 100;
class Init {
static const int *p_i;
};
const int* Init::p_i = &i;
Reference:
ANSI/ISO C++ 9.4.2 9.2(4)
2322 object of abstract class type %t is not allowed
Cause:
By definition, objects of abstract types cannot be created; any such attempt will be flagged as an error by the compiler.
Example:
class Base {
virtual void foo() = 0;
};
Base b;
Action:
Either remove the statement that attempts to create an object of an abstract class type or make the class concrete/ non-abstract by removing the pure virtual functions.
Reference:
ANSI/ISO C++ 10.4(3)
2323 function returning abstract class %t is not allowed
Cause:
An abstract class cannot be used as a function return type, parameter type or as the type of an explicit conversion.
Example:
class Base {
virtual void foo() = 0;
};
class Derived : public Base {
Derived bar();
};
Action:
Do not declare a function to accept as paramater or return an abstract class type.
Reference:
ANSI/ISO C++ 10.4(3)
2329 local class member %n requires a definition
Cause:
Member functions of local classes must be defined within the class definition.
Example:
int main() {
struct Struct {
void foo();
};
Struct s;
s.foo();
}
Action:
Define all required member functions of the local classes inside the class itself.
Reference:
ANSI/ISO C++ 9.8(2)
2336 unknown external linkage specification
Cause:
The linkage specification provided in the code is not known to this compiler implementation. The C and C++ linkage are two linkage specifications that a standard conformant compiler should support and linkage specifications for other languages are implementation defined.
Example:
extern "XYZ" int foo();
Action:
Provide a valid linkage specification allowed by the compiler,like C or C++ , for example:
extern "C" int foo();
Reference:
ANSI/ISO C++ 7.5 (3)
2340 value copied to temporary, reference to temporary used
Cause:
References should be initialized to refer to a valid object or a function. In certain contexts, when rvalues are used for initializing references, the compiler might create a temporary and bind that to the reference. In such scenarios compiler will issue this diagnostic.
Example:
struct Init {
const int & mem;
Init() : mem(10) {}
};
Action:
Provide a proper object for initializing the reference.
Reference:
ANSI/ISO C++ 8.5.3 12.2
2363 invalid anonymous union -- nonpublic member is not allowed
Cause:
Anonynous unions can have only public non-static data members, private or protected members are not allowed.
Example:
static union {
private:
int i;
protected:
float f;
};
Action:
Provide public access to all the anonymous union members. For example:
static union {
public:
int i;
float f;
};
Reference:
ANSI/ISO C++ 9.5(3)
2364 invalid anonymous union -- member function is not allowed
Cause:
Anonynous unions cannot have member functions, they can only contain non-static data members.
Example:
static union {
int foo() { return 0; }
};
Action:
Remove the member function from anonymous union.
Reference:
ANSI/ISO C++ 9.5(3)
2487 inline %n cannot be explicitly instantiated
Cause:
When explicit instantiation of a class template is done, inline functions will not be instantiated. This diagnostic is just to mention this fact.
Example:
template <typename T>
class X {
void foo() {}
};
template class X<int>;
Action:
Providing explicit instantiations for templates is a old programming style and it is not recommended. Check if you really need to do explicit instantiations in your code.
Reference:
ANSI/ISO C++ 14.7.2
2549 "variable" is used before its value is set
Cause:
A variable's value has been used without being set. The algorithms that detect this situation only report it
once for a given variable, and not necessarily at the first use of the uninitialized value.
Example:
int i;
printf("%d", i);
Action:
Provide the variable with a value before the variable is used. If you only provide a value for the use reported here, you may find that when you recompile your program another uninitialized use is detected. It is best to initialize variables as close as possible to the point of declaration.
Reference:
2656 transfer of control into a try block
Cause:
Goto statements cannot be used to transfer control inside the try blocks.
Example:
goto LABEL;
try {
LABEL:
throw 0;
} catch(...) {
}
Action:
Remove the goto statement that transfers the control inside the try block.
Reference:
ANSI/ISO C++ 15(2)
2767 conversion from pointer to smaller integer
Cause:
The 64-bit pointer is being cast to an integer type that is smaller in size. Casting a 64-bit pointer to a smaller integer type is undefined behavior. This also could indicate code that relies on pointers and integers being the same
size. The code will cause an unexpected loss of data on 64-bit platforms.
Example:
int *p = 0;
int i = (int) p;
Action:
If this is the intended behavior, first cast the pointer to a 64-bit integer, then cast the result to the desired integer type.
Reference:
2830 %n has no corresponding operator delete%s (to be called if an exception is thrown during initialization of an allocated object)
Cause:
For operator new, a corresponding operator delete needs to be provided so that it can be called for proper destruction in case an exception is thrown during the initialization of the allocated object.
Example:
void* operator new(unsigned long, void*) { return 0; }
struct Pool {
Pool() { }
} object;
Pool* allocate() { return new (&object) Pool(); }
Action:
Provide a corresponding operator delete to be called if an exception is thrown during the initialization of the allocated object.
Reference:
2836 returning reference to local variable
Cause:
It is incorrect to return a reference to a local variable as the return value from a function. This is because the lifetime of a local variable ends once the function returns.
Example:
int& foo() {
int i = 10;
return i;
}
Action:
Do not return reference to a local variable; if you really want to return a reference, make the local variable static. This is because the lifetime of a static variable is same as lifetime of the program.
Reference:
2837 omission of explicit type is nonstandard ("int" assumed)
Cause:
A declaration or a definition does not have an explicit type, int will be assumed as the type but this
behavior is non-standard.
Example:
extern i;
a();
b(){}
extern c();
extern d(){}
Action:
Add an explicit type for the declaration or definition.
Reference:
C99 6.7.2(2), ANSI/ISO C++ 7.1.5(2)
3055 types cannot be declared in anonymous unions
Cause:
Anonynous unions can only define non-static data members. You cannot declare types or functions within anonymous unions.
Example:
static union {
typedef int T;
T i;
};
Action:
Remove the typedef from the anonymous union. Either declare the members without the typedef type or provide the typedef outside the anonymous union. For example:
static union {
int i;
};
Reference:
ANSI/ISO C++ 9.5(2)
3056 returning pointer to local variable
Cause:
The return value of the function is the address of a local variable. Unless declared as static, a local variable has automatic storage duration
i.e. the storage for it lasts until the block that defines it exists. Dereferencing the pointer to a local variable after the function that defines it returns will lead to undefined runtime
behavior.
Example:
int* foo() {
int i = 10;
return &i;
}
Action:
If you need to return the pointer to this variable then make it a static variable.
Reference:
ANSI/ISO C++ 3.7.2
3138 format argument does not have string type
Cause:
The format argument of a function having same attributes as the printf, scanf family functions must be of string type.
Example:
int print(char *str,void *fmt, ...)
__attribute__((format(printf,2,3))); // argument 2 must be of
// string type
Action:
Change the type of format argument to string type
Reference:
3290 Passing a non-POD object to a function with variable arguments has undefined behavior. Object will be copied onto the stack instead of using a constructor.
Cause:
A non-POD (POD stands for "plain old data") object is being passed to a function with variable arguments. Object will be copied onto the stack instead of using a constructor.Varargs do not know how to deal with non-POD types, this can lead to undefined
behavior.
Example:
class A {
int i;
};
int foo(char*, ...);
int bar() {
A a;
foo("hello",a);
return 0;
}
Action:
Do not pass non-POD object to a function with variable arguments. If this is essential write a conversion operator to convert from non-POD to POD type and call that operator before passing the object to the variable arguments function.
Reference:
3353 %n has no corresponding member operator delete%s (to be called if an exception is thrown during initialization of an allocated object)
Cause:
For member operator new, a corresponding member operator delete needs to be provided so that it can be called for proper destruction in case an exception is thrown during the initialization of the allocated object.
Example:
struct Pool {
Pool() { }
void* operator new(unsigned long, void*) { return 0; }
} object;
Action:
Provide a corresponding member operator delete to be called if an exception is thrown during the initialization of the allocated object.
Reference:
4212 mismatch between character pointer types %t1 and %t2
Cause:
C allows conversion between pointers to interchangeable types, but this can be unsafe. Mismatch between character pointer types is diagnosed with a unique message so it can be suppressed if desired.
Example:
int foo(char *x, unsigned char *y) {
x = y; // warning 4212 here
}
Action:
If this conversion is safe for your code, then suppress this warning by providing an explicit cast.
Reference:
C99 6.3.2.3
4225 suggest parentheses around comparison in operand of %sq
Cause:
The bitwise operator | has lower precedence than the comparison operator, possibly changing the semantics of the
expression. This can be caused by other combinations of comparison and bitwise operators as well.
Example:
bool check(unsigned p1, unsigned p2, unsigned mask) {
return ( p1 == p2 | mask );
}
Action:
Disambiguate the expression by using explicit parenthesis around the bitwise
operator, thus
return ( p1 == (p2 | mask) );
Reference:
4227 padding struct with %s1 bytes to align member %sq2
Cause:
The compiler has added s1 bytes before a member so that it will be aligned and hence accessed efficiently.
Example:
typedef struct {
int field1;
double field2;
} str;
Action:
Insertion of padding bytes themselves is not a problem but you need to ensure that you do not use hard coded offsets for accessing fields of the struct through pointers, use offset of macro instead. In some cases the number of padding bytes being inserted can be reduced by reordering the fields.
Reference:
4228 64 bit migration: conversion from %t1 to a more strictly aligned type %t2 may cause misaligned access
Cause:
The compiler has detected conversion of pointers from a lesser aligned type to a more strictly aligned type. This usually happens when assigning an int pointer to a long pointer.
This is not a problem in 32 bit mode since int and long are both 4 bytes aligned but in 64 bit mode int is 4 byte aligned whereas long is 8 bytes aligned. Because of the difference in alignment in 64 bit mode this conversion might cause unaligned access in 64 bit mode.
Example:
int a = 10;
long *lptr = (long *)&a;
Action:
For 64 bit portability ensure that your code does not assign a pointer to int to a pointer to long.
Reference:
4229 64 bit migration: conversion from %t1 to %t2 may truncate value
Cause:
The compiler has detected conversion from a larger type to a smaller type. This usually happens when converting a pointer or long value to an int. This is not a problem in 32 bit mode since int, long and pointer all are of same size (32 bit) but in 64 bit mode int is 32 bit whereas long and pointer are 64 bit. Because of the difference in size in 64 bit mode this conversion might lead to truncation of value.
Example:
void foo(long l) {
int i = l;
}
Action:
For 64 bit portability ensure that your code does not convert from pointer and long values to int.
Reference:
4230 64 bit migration: conversion from %t1 to %t2 may cause target of pointers to have a different size.
Cause:
The compiler has detected conversion between pointers to data types having different sizes. This usually happens when
assigning an int pointer to a long pointer or vice versa.
This is not a problem in 32 bit mode since int, long and pointer all are of same size (32 bit) but in 64 bit mode
int is 32 bit whereas long and pointer are 64 bit. Because of the difference in size in 64 bit mode this conversion might lead to incorrect
behavior in 64 bit mode.
Example:
long l = 1;
long *lptr = &l;
int *iptr = (int *)lptr;
Action:
For 64 bit portability ensure that your code does not convert from pointer to int to pointer to long and vice versa.
Reference:
4231 64 bit migration: conversion between types of different sizes has occurred (from %t1 to %t2 )
Cause:
The compiler has detected conversion between data types having different sizes. This usually happens when converting from int data type to pointer or long data type and vice versa. This is not a problem in 32 bit mode since int, long and pointer all are of same size (32 bit) but in 64 bit mode int is 32 bit whereas long and pointer are 64 bit. Because of the difference in size n 64 bit mode this conversion might lead to incorrect
behavior in 64 bit mode.
Example:
void foo(int i) {
foo((void*)i);
return i;
}
Action:
For 64 bit portability ensure that your code does not convert from int to pointer or long and vice versa.
Reference:
4232 conversion from %t1 to a more strictly aligned type %t2 may cause misaligned access
Cause:
A pointer is being cast from a lesser aligned type to a more strictly aligned type. Accesses using the new type may cause misaligned access.
Example:
int foo(int* p, long long* l) {
l = (long long*) p; // warning 4232 here
}
Action:
Correct the code that uses such conversions.
Reference:
ANSI/ISO C++ 3.9, 3.9.1, 3.9.2
4239 case type mismatch with switch expression type
Cause:
The switch expression type does not match with the type of case labels.
Example:
enum BOOLEAN { TRUE = 0, FALSE = 1 };
BOOLEAN a_bool = TRUE;
switch(a_bool) {
case 0: printf("true\n");
case 1: printf("false\n");
default: printf("no match found \n");
}
Action:
Fix your source code to ensure the type of the switch expression and case labels is same.
Reference:
4242 No prototype or definition in scope for call to %sq
Cause:
Prototypes are optional in ANSI C, however their use can prevent a wide range of common programming errors which are otherwise difficult to detect. This call site provides no prior prototype or definition so the compiler cannot verify the correctness of the argument list.
Example:
int main() {
foo(10.0f);
}
Action:
Provide a prototype declaration for the function before calling that function.
Reference:
4247 function called with different argument counts (%s vs. %s2)
Cause:
Two calls to an unprototyped function differ in the number of arguments being passed, at least one of these calls is passing wrong arguments.
Example:
int main() {
foo(10);
foo(10, 100);
}
Action:
Correct the function call which is passing wrong number of arguments. Preferably declare the function before calling it.
Reference:
4248 comparison of unsigned integer with a signed integer
Cause:
This occurs due to mixing signed and unsigned operands with relational operators <, ≤, >, ≥. One of the operands in signed and the other unsigned. The signed quantity may be negative as well.
Example:
int a = -1;
unsigned int b = 1;
if (a < b)
return a;
Action:
To resolve this problem, either cast the integer to unsigned if you know it can never be less than zero or cast the unsigned to a signed int if you know it can never exceed the maximum value of int.
Reference:
4249 64 bit migration: value could be truncated before cast to bigger sized type.
Cause:
The size of the result of an operation is determined based on the size of the operands and not based on the type into which the resultant value is being
castled. If the result exceeds the size of the operands, in this case 32 bits, it will be truncated even before the cast takes place.
Example:
void foo(int data) {
long data1 = (long) (data << 16); // warning 4249 here
long data2 = ((long)data) << 16; // no warning
}
Action:
If you expect the value of the result to exceed the size of the type of operands then cast the operands to the bigger type before the operation.
Reference:
4253 unsigned value cannot be less than zero
Cause:
An ordered comparison between an unsigned value and a constant that is less than or equal to zero often indicates a programming error.
A negative value is converted to an unsigned value before the comparison, so any negative value compares larger than
most unsigned values. If the code is correct, the comparison could be more clearly coded by testing for equality with zero.
Example:
int main() {
unsigned data = 30;
if(data <= 0)
return 1;
}
Action:
Cast (or otherwise rewrite) one of the operands of the compare to match the signedness of the other operand, or compare for equality with zero.
Reference:
4255 padding size of struct %sq1 with %s2 bytes to alignment boundary
Cause:
Padding bytes have been inserted for proper alignment of the struct.
Example:
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
int main() {
struct X {
uint32_t data_size;
uint8_t status;
};
}
Action:
Insertion of padding bytes themselves is not a problem but you need to ensure that you do not use hard coded offsets for accessing fields of the struct through pointers, use offset of macro instead. In some cases the number of padding bytes being inserted can be reduced by reordering the fields.
Reference:
ANSI/ISO C++ 18.1(5)
4259 suggest parentheses around the operands of %sq
Cause:
A possibly incorrect combination of [in]equality and bitwise operations. Passing a boolean argument to a bit operation is quite unusual and usually happens because of programming errors like missing parentheses around operands of "&" and "|"
Example:
return (i == j | k); // warning 4259 here
^
== has higher precedence than | and hence will be evaluated first, this is probably not what the programmer intended. For j|k to be evaluated first put parentheses around j|k.
Action:
When using bit operations in combination with [in]equality, put parentheses around operands of bitwise operators.
Reference:
4264 padding size of struct anonymous with %s bytes to alignment boundary
Cause:
Padding bytes have been inserted for proper alignment of the anonymous struct.
Example:
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
int main() {
typedef struct {
uint32_t data_size;
uint8_t status;
} str;
}
Action:
Insertion of padding bytes themselves is not a problem but you need to ensure that you do not use hard coded offsets for accessing fields of the struct through pointers, use offset of macro instead. In some cases the number of padding bytes being inserted can be reduced by reordering the fields.
Reference:
ANSI/ISO C++ 18.1(5)
4273 floating-point equality and inequality comparisons may be inappropriate due to
round off common in floating-point computation
Cause:
Since floating point numbers are usually subject to rounding-off errors, comparison between non-constant floating point values may not always be accurate.
Example:
bool check(float v1, float v2) {
return ( v1 == v2 );
}
Action:
Change your program logic to not depend on such comparisons.
Reference:
4274 comparison of pointer with integer zero
Cause:
A pointer is being compared with an integer zero. Equality comparison with integer zero is allowed for checking if the pointer is null but other comparisons like >, <, ≥ and ≤are not valid.
Example:
int main() {
char* ptr = 0;
if(ptr >= 0)
return 1;
}
Action:
Rewrite the expression to use == or !=.
Reference:
4275 constant out of range (%s) for the operator
Cause:
For a given relational operation the constant is out of range specified by the other non-constant operand.
Example:
void foo(bool b, char c) {
if (b == 3) { } // warning 4275 here
if (c < 200) { } // warning 4275 here
if ((unsigned char)c < 200) { } // no warning here
}
Action:
Check the value of the constant being used in the operation. In the scenarios where the comparison is between signed and unsigned types the problem can be fixed by using a cast.
Reference:
4276 relational operator %sq always evaluates to 'false'
Cause:
The greater than or less than relational operation in the expression always evaluates to false. This happens when comparing against the largest and smallest values in the range of given type.
Example:
void foo(unsigned char c) {
if (c > 255) {} // warning 4276 here
}
NOTE: 255 is the largest value for an unsigned char so a >
comparison will always be false.
Action:
Check the value of the constant being used in the operation.
Reference:
4277 logical AND with a constant, do you mean to use '&'?
Cause:
Using a constant in a logical AND (&&) operation is rather unusual. This usually indicates a typo where the programmer actually meant to say bitwise AND (&). This warning is not generated for the constant 0 since that often results from macro expansions.
Example:
result = value && 0x1; // warning 4277 here
Action:
Check if you meant to use '&' instead of '&&'. For certain macro expansions this can be valid code, suppress this warning for those macros using the +Wmacro option.
Reference:
4278 the sub expression in logical expression is a constant
Cause:
Logical operators follow short-circuit evaluation - if the first operand of a logical || or && operator determines the result of the expression, the second operand will not be
evaluated. In the given expression the first sub expression is a constant that determines the result of the expression and hence the rest of the expression will never be evaluated.
Example:
int main() {
int a = 10;
if( 10 || (a == 10))
return 0;
}
Action:
Check if the constant is expected. In some cases the constant value might be the result of a valid macro expansion, in such scenarios you can suppress this warning for the particular macro using the +Wmacro option.
Reference:
4279 the expression depends on order of evaluation
Cause:
The expression modifies a variable more than once without an intervening sequence point OR the expression modifies a variable and fetches its value in a computation that is not used to produce the modified value without an intervening sequence
point. The final value of such expressions is undefined.
Example:
i = i++; // warning 4279 here
x = i + ++i; // warning 4279 here
i = i + 1; // no warning here
Action:
Rewrite the expression so that each variable is modified only once before a sequence point OR if a variable is modified, it is fetched only to compute the value to be stored in the variable (ex i = i+1).
Reference:
C99 6.5, ANSI/ISO C++ 5.4
4286 return non-const handle to non-public data member may undermine encapsulation
Cause:
A less-restrictive member function is returning a non-const reference or pointer to a more-restrictive data member. Since the handle thus returned is not a const, the caller will be able to modify the restrictive data member, thus violating the norms of encapsulation.
Example:
class Capsule {
public:
int& getvalue_ref() { return private_data; }
int* getvalue_ptr() { return &private_data; }
private:
int private_data;
} object;
Action:
Declare the member functions to return a const handle instead.
Reference:
4289 endian porting: the definition of the union may be endian dependent
Cause:
The values accessed using the members of a union may differ based on endianness of a machine on which code is executed. This happens if the union has an integral member, which depends on endianness, and a character member, which does not depend on endianness, and the value of the union is stored using one
member and accessed using the other.
Example:
union Endian { char c[4]; int v; }; // warning 4289 here
int foo() {
union Endian u = { 0x11, 0x22, 0x33, 0x44 };
int i = u.v;
return i;
}
// On a big endian machine value of i will be 0x11223344 whereas
// on a little endian machine it will be 0x44332211
Action:
For portable code change the way this union is used. Do not use unions for converting values from one type to another.
Reference:
4290 endian porting: the initialization of char array may be endian dependent
Cause:
A char array is being initialized using hexadecimal values. It is likely that this array will later be accessed as an
integer. Based on endianness of a machine on which code is executed the value of this integer will differ.
Example:
char a[4] = { 0x11, 0x22, 0x33, 0x44 }; // warning 4290 here
Action:
For portable code check how this array is used.
Reference:
4292 endian porting: the dereference of cast pointer may be endian dependent
Cause:
A pointer of integral type is being cast to a pointer of char or smaller integer type. Based on endianness of a machine on which code is executed the value accessed using will differ.
Example:
unsigned int value = 0x03020100;
unsigned int *ptr = &value;
unsigned char charVal;
void foo() {
charVal = *(unsigned char *)ptr; // warning 4292 here
charVal = *(unsigned char *)(void*)ptr; // no warning
}
Action:
For portable code change the way these values are accessed. If the order in which the values are accessed is not important then first cast the pointer to void* type and then cast to the lesser integer type.
Reference:
4295 abstract function type declared with empty parentheses, consider replacing with parameter list or void.
Cause:
The declaration of function has an empty parameter list. If the function has
parameters, they should be declared here; if it has no parameters,void should be specified in the parameter list.
Example:
void foo(long (*compar) ()) ;
Action:
The recommended way to declare a function that takes no parameters is to use void in the parameter list.
Reference:
4298 64 bit migration: addition result could be truncated before cast to bigger sized type
Cause:
The size of the result of an operation is determined based on the size of the operands and not based on size of variable in which the resultant value is stored. If the result exceeds the size of the operands, in this case 32 bits, it will be truncated even before the assignment takes place.
Example:
void foo(int data) {
long data1 = data + 16; // warning 4298 here
long data2 = ((long)data) + 16; // no warning
}
Action:
If you expect the value of the result to exceed the size of the type of operands then cast the operands to the bigger type before addition else use same type for operands and result.
Reference:
4299 64 bit migration: multiply result could be truncated before cast to bigger sized type
Cause:
The size of the result of an operation is determined based on the size of the operands and not based on size of variable in which the resultant value is stored. If the result exceeds the size of the operands, in this case 32 bits, it will be truncated even before the assignment takes place.
Example:
void foo(int data) {
long data1 = data * 16; // warning 4299 here
long data2 = ((long)data) * 16; // no warning
}
Action:
If you expect the value of the result to exceed the size of the type of operands then cast the operands to the bigger type before multiplication else use same type for operands and result.
Reference:
4301 expression has no effect
Cause:
The expression has no effect or side-effect.
Example:
#define foo(A) 0
int main() {
int A = 0;
foo(A);
}
Action:
Remove or correct the expression. In some cases the expression might be the result of a valid macro expansion, in such scenarios you can suppress this warning for the particular macro using the +Wmacro option.
Reference:
20036 variable %s (field %s) is used before its value is set
Cause:
The compiler has detected use of a member of a struct variable before it's value is set.
Example:
struct foo
{
int a;
int b;
};
int func()
{
struct foo x;
x.a = x.b + 10; // warning 20036 for use of field b
return 0;
}
Action:
Initialize the struct member with a value before it's use. This may not be the only use of the uninitialized
value. So it is best to initialize the field as close as possible to the point of struct variable declaration.
Reference:
20037 variable %s may be used before its value is set
Cause:
The compiler has detected use of a variable which might not always be used initialized before this use. One or more execution paths that lead to this use do not initialize this variable.
Example:
int func(int a)
{
int b,c;
if (a > 10)
b = a;
c = b + 10; // warning 20037 for use of variable b
return c;
}
Action:
Check if all the execution paths leading to the usage of reported variable initialize it. To avoid such issues it is best to initialize the variable close to the point of declaration.
Reference:
20048 %s "%s" has incompatible type with previous declaration at line %s in file "%s"
Cause:
The declaration of a global variable or function does not match the corresponding declaration on a different file.
Example:
-- file1.c ----
typedef struct {
int f;
int g;
} A;
A global; // LINE 6
void print_A(A par) // LINE 8
{
printf("%d %d", par.f, par.g);
}
-- file2.c ----
typedef struct {
int f;
char g; // Should be: int g;
} A;
A global;
void print_A(A);
main()
{
print_A(global);
}
"file1.c", line 8: warning #20048-D: Function "print_A" has incompatible
type with previous declaration at line 8 in file "file2.c"
"file2.c", line 6: warning #20048-D: Variable "global" has incompatible
type with previous declaration at line 6 in file "file1.c"
Action:
In the case of mismatch for a global variable, review the 2 locations specified in the warning and make sure that the declared global types match. In the case of a function, review the 2 locations specified in the warning and verify that the types of the arguments and return value match for the two function declarations. This problem can usually be avoided by using header files to declare types or
functions used across multiple source files.
Reference:
20200 Potential null pointer dereference %s%s is detected %s
Cause:
A reference through a pointer whose value may be null has been detected. The pointer could have been conditionally initialized or assigned with the return value of a
function that may return NULL.
Example:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void nullptr3 ()
{
char *p = malloc (20); // LINE 6
strcpy (p, "nullptr3");
FILE* f = fopen("blah","r"); // LINE 8
if (p != NULL)
fread(p,20,1,f);
printf ("%s", p);
}
"file1.c", line 7, procedure nullptr3: warning #file1-D: Potential null
pointer dereference through p is detected (null definition:file1.c,
line 6)
"file1.c", line 10, procedure nullptr3: warning #file1-D: Potential null
pointer dereference through f is detected (null definition:file1.c,
line 8)
Action:
If you are assigning NULL to a pointer, make sure that no path in the program can dereference that pointer before it is assigned a different value. For routines that may return a NULL, check or assert that the value returned is not NULL.
char * pc = malloc(20);
if (pc != NULL)
strcpy(pc, "hello");
or:
char * pc = malloc(20);
assert(pc != NULL);
strcpy(pc, "hello");
Reference:
20201 Memory leak is detected
Cause:
A memory leak is detected for the memory allocation done at the location mentioned in the message.
Example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int leak1 (int k)
{
char *p = malloc (k); // LINE 6
strcpy (p, "hello");
printf ("%s", p);
return 0;
}
"memleak.c", line 6, procedure leak1: warning #20201-D: Memory
leak is detected.
Action:
Make sure that the pointer allocated at the location mentioned in the diagnostic is freed correctly.
Reference:
20202 Allocated memory may potentially be leaked %s
Cause:
A memory leak may occur for the memory allocation done at the location mentioned in the message. It is possible that the memory may be leaked along one of the paths from the allocation site.
Example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int* leak2(int k, char* fname)
{
FILE* f;
int *p = (int*) malloc(k); // LINE 7
if (p == 0)
return 0;
if (k > 10)
return 0; // LINE 11
return p;
}
"memleak.c", line 7, procedure leak2: warning #20202-D: Allocated memory
may potentially be leaked (at line 11)
Action:
Make sure that the pointer allocated at the location mentioned in the diagnostic, is freed correctly along all
paths. For example, in the above case, if (k > 10), we return 0 without freeing p. After this point, p is unreachable from other
pointers. Hence it is a potential memory leak along this point.
Reference:
20203 Potential out of scope use of local %s %s
Cause:
A local variable's address is being returned and dereferenced in the caller, or allocated memory is being returned and used in the caller or a variable defined in the inner scope is being accessed indirectly in the enclosing scope. Use of local variable outside its scope can lead to unexpected
behavior.
Example:
#include<stdio.h>
int foo()
{
int *p;
{
int q;
scanf("%d", &q);
p = &q;
}
// out of scope reference to q
return *p;
}
int main()
{
int result = foo();
return result;
}
"oos.c", line 11, procedure foo: warning #20203-D: Potential out of scope use
of local variable q
Action:
Check that the local variable mentioned in the diagnostic does not have its address taken and returned to the caller function or an allocated memory pointer is not returned to the caller.
Reference:
20206 Out of bound access (%s)
Cause:
The expression is accessing out of object's memory boundary. The object could be an array, a heap memory buffer, or a string.
Example:
#include <string.h>
char buf[12];
struct A {
int f1;
int f2;
};
int i;
struct A a;
void foo()
{
char c = 'd';
i = *(int *)&c; // LINE 12
memset(buf, 0, 21); // LINE 13
memset(&a.f1, 0, sizeof(a)); // LINE 14
}
line 12, procedure foo: warning #20206-D: Out of bound access (In
expression "memset( (char*)buf, 0, 21 )", variable "buf" [j.c:2]
(type: char [12]) has byte range [0 .. 11], writing byte range [0
..20].)
line 13, procedure foo: warning #20206-D: Out of bound access (In
expression "*(int*)&c", variable "c" [j.c:11] (type: char ) has 1
byte, reading byte range [0 .. 3].)
line 14, procedure foo: warning #20206-D: Out of bound access (In
expression "memset( (char*)&(&a)->f1, 97, 8 )", &(&a)->f1 (type:
int) has byte range [0 .. 3], writing byte range [0 .. 7].)
Action:
Fix the out of bounds access if it is a real bug. Change the code to remove out of bound access if it is false positive.
i = c;
memset(buf, 0, sizeof(buf);
memset(&a, 0, sizeof(a));
Reference:
20208 Forming out of bound address(%s)
Cause:
The expression is forming an address which is out of object's memory boundary.
Example:
char buf[12];
char *p;
void foo()
{
int i = 20;
p = &buf[0] + i; // LINE 7
}
line 7, procedure foo: warning #20208-D: Forming out of bound
address (In expression "&buf[0]+20", variable "buf" [test.c:1]
(type: char [12]) has byte range [0 .. 11], forming address byte
[20].)
Action:
Fix the forming out of bounds access if it is a real bug.
Reference:
20210 Mismatch in allocation and deallocation
Cause:
The compiler has detected a code that uses different methods for memory allocation and it's corresponding deallocation. A memory allocated using malloc() and it's variations should be deallocated only by using free() and memory allocated using new operator should be deallocated only by using delete. Memory allocated using alloca() should not be deallocated using either free() or delete.
Example:
1 #include
2 #include
3
4 char* allocate()
5 {
6 return (char*)malloc(sizeof(char)*100);
7 }
8
9 void xyz()
10 {
11 char *str = allocate();
12 delete str;
13 }
"20210.C", line 12, procedure xyz: warning #20210-D: Mismatch in allocation
and deallocation
Action:
Replace the deallocator function call/operation with the one corresponding to the allocator or the vice versa.
Reference:
20213 Potential write to read only memory %s%s is detected
Cause:
The code is trying to modify an area of the memory that has been defined as read-only.
Example:
#include <stdlib.h>
#include <stdio.h>
const char * astring = "foo";
const char * bstring = "bar";
void mod_astring()
{
char* w = (char*) astring;
*w = 'g'; // LINE 9
}
int x;
void mod_bstring()
{
char* s;
if (x == 11)
s = (char*) bstring;
else
{
s = (char*) malloc(128);
if (s == 0) exit(1);
}
sprintf(s,"%d",x); // LINE 25
puts(s);
}
line 9, procedure mod_astring: warning #20213-D: Potential write to
readonly memory through astring is detected
line 25, procedure possible: warning #20213-D: Potential write to
readonly memory through s is detected
Action:
Look at the definition of the memory written to and make sure that it is not defined as "const".
Reference:
Copyright©2007 Hewlett-Packard Development Company, L.P.