How to drop the warning “conversion to ‘char’ from

2020-04-30 02:13发布

问题:

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.

回答1:

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.



回答2:

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.



回答3:

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.



回答4:

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.



标签: c casting