I though that if I cast
a number like this (unsigned char)32
it will be enough to fix the compiler warning, but it wasn't like how I planed.
Here i have the following part of the program which actually explain the problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void){
char *ptr = malloc(6);
const char *name = "MICHI";
unsigned int i = 0;
if(ptr){
strcpy(ptr, name);
ptr[strlen(ptr)] = '\0';
}else{
return 1;
}
while(ptr[i] != '\0'){
if((ptr[i] >= 'A') && (ptr[i] <= 'Z')){
ptr[i] += (unsigned char)32;
}
i++;
}
printf("Name = %s\n",ptr);
if(ptr){
free(ptr);
ptr = NULL;
}
}
When I try to compile it with compiler warnings ON, I get this:
error: conversion to ‘char’ from ‘int’ may alter its value [-Werror=conversion]|
This means thet the following ptr[i] += (unsigned char)32;
doesn't provide a solution to my problem.
My question is, how to drop this warning because I have no clue about it.
Ideone doesn't helps to much, because I think that all warnings are Turned off.
OP is using a level of warning that is very picky
warning: conversion to 'char' from 'int' may alter its value [-Wconversion]
// Both cause the warning
ptr[i] += (unsigned char) 32;
ptr[i] = tolower(ptr[i]);
To address the warning, be explicit
ptr[i] = (char) (ptr[i] + 32);
ptr[i] = (char) tolower(ptr[i]);
[Detail] Operations that involving narrow type like char, short, unsigned char, _Bool, ...
will have that operand promoted, using the usual integer promotions to int/unsigned
, like ptr[i]
. So assigning that int/unsigned
back to a char
triggers the warning. An explicit cast of the result quiets the warning.
Many compilations omit the [-Wconversion] or equivalent
option and so will not see the warning.
Adding to the comments, there is actually a way of silencing the warning using casts only:
ptr[i] = (char)((int)ptr[i] + 32);
This way the deal with the conversion is delegated to the assignment operator, which is (as pointed by @Olaf) defined in the Standard, 6.5.16.1p3.
This line:
ptr[i] += (unsigned char)32;
really means:
ptr[i] = ptr[i] + 32;
Now... ptr[i]
may legally be as big as 255. And if you added 255 + 32, you'd get 287.
How do you propose to fit value 287 inside a char
, which has a maximum value of 255?
You just cannot do that. That is what the error is about.
If you want to get rid of the error, you must first be clear in your own mind about what exactly you want to happen when addition might create values larger than a char
can hold.
If you are simply trying to convert the letters A-Z into their lowercase equivalents, just use the appropriate api for that: tolower
If you're really not going to use tolower
, then try this:
ptr[i] = (unsigned char)(ptr[i] + 32);
The important difference is that the type-cast is on the result of the calculation, and not on one of the operands of the operation.
The warning is because there is a possibility that you may overrun the boundary of a char
value.
Usually, avoiding the warning is not a good idea, in general.
Use tolower()
to get the job done in a cleaner way.