I am having trouble with the following code:
#include <stdio.h>
#include <stdlib.h>
void someFunction(int number);
int main()
{
printf("Hello world!\n");
return 0;
}
void someFunction(int number)
{
char* string = (char*) malloc((number+1)*sizeof(char));
}
When I run it on my computer with the Code::Blocks IDE and the GNU GCC compiler it works without any problems. But when I use it on another machine (also with Code:Blocks and LLVM Clang Compiler compiler) I get the error
implicit conversion changes signedness: 'int' to 'unsigned long' [-Werror,-Wsign-conversion]
This error refers to the line
char* string = (char*) malloc((number+1)*sizeof(char));
If I get the error message correctly there is some "int" that is implicitly converted to "unsigned long", but I do not see where this happens.
Could you please explain this to me?
It is a warning considered by the compiler as an error due to the compiler options -Werror
and -Wsign-conversion
.
Within the expression
(number+1)*sizeof(char)
used in the call of malloc
the operand sizeof( char )
has unsigned integer type size_t
that is an alias for the type unsigned long
. On the other hand, the operand number+1
has the signed type int
. The rank of the type size_t
is higher than the rank of the type int
. It means that due to the usual arithmetic conversions the operand of the type int
will be implicitly converted to the type size_t
and thus can lose its sign.
To resolve the problem just declare the function parameter like
void someFunction(size_t number);
There is no sense to pass a signed value to the function that allocates memory. And moreover the parameter of the function malloc
has the type size_t
.
To make it clear then consider the following simple program.
#include <stdio.h>
int main( void )
{
int number = -1;
printf( "( size_t )number = %zu\n", ( size_t )number );
}
Its output might look like
( size_t )number = 4294967295
As you can see the negative variable number
of the type int
converted to the unsigned integer type size_t
becomes a very big unsigned integer.