【问题标题】:How do I get rid of the following sign-conversion warning?如何摆脱以下符号转换警告?
【发布时间】:2020-02-07 22:14:20
【问题描述】:

每当调用函数 initSetArray() 时,我都会收到以下警告:

error: conversion to ‘long unsigned int’ from ‘int’ may change the sign of the result [-Werror=sign-conversion]
  setarray = (set*)malloc(sizeof(set) * number_of_sets);   

函数 initSetArray 只是简单地初始化 setarray。

void initSetArray(set *setarray, int number_of_sets, int number_of_blocks)
{
    setarray = (set*)malloc(sizeof(set) * number_of_sets);
}

我已经定义了两个结构,它们在上面定义的辅助函数中使用:

typedef struct{
    uint64_t tag;   // For identifying the block
    uint8_t valid;  // Valid bit for the block
    uint8_t dirty;  // Dirty bit for the block
} block;

typedef struct{
    uint64_t index; // For identifying the set
    block* way;
} set;

我无法准确找出哪个变量属于“long unsigned int”类型。我可以做些什么来解决这个问题?

【问题讨论】:

  • 不是你的问题,但如果你希望调用者看到分配的setarray,你需要传递set**而不是set*

标签: c gcc warnings unsigned


【解决方案1】:

在此声明中

setarray = (set*)malloc(sizeof(set) * number_of_sets);

变量number_of_sets 是一个整数(int),因为它用在带有sizeof (size_t) 的表达式中,所以该值被转换为匹配。

size_t 通常是unsigned long。如果你不喜欢这个警告,这会解决它:

setarray = (set*)malloc(sizeof(set) * (size_t) number_of_sets);

【讨论】:

    【解决方案2】:

    malloc 函数采用size_t 参数,size_t 为您的构建定义为unsigned long int(通常是这样)。在您的通话中:

    setarray = (set*)malloc(sizeof(set) * number_of_sets);
    

    您将这样的 size_t 值(sizeof 运算符给出 size_t)乘以(有符号的)int 变量 - 因此是警告。

    为避免这种情况,number_of_sets 显式转换为size_t,如下所示:

    setarray = (set*)malloc(sizeof(set) * (size_t)number_of_sets);
    

    或者,更好的是,将该参数的类型更改为size_t

    void initSetArray(set *setarray, size_t number_of_sets, size_t number_of_blocks)
    {
        setarray = (set*)malloc(sizeof(set) * number_of_sets);
    }
    

    通常,当使用表示对象的“计数”或“大小”的变量时,unsigned int 是首选(除非您可以真的具有负计数或大小)。

    【讨论】:

      【解决方案3】:

      警告是在非常严格的警告设置下产生的,因为值number_of_sets 隐式地从int 转换为无符号类型unsigned long int,对于负值number_of_sets,它可能具有违反直觉的值。

      要消除此警告,您可以:

      • 更改initSetArray 的原型以修复参数的类型:number_of_setsnumer_of_blocks 应该是size_t 类型的无符号值:

        void initSetArray(set *setarray, size_t number_of_sets, size_t number_of_blocks)
        
      • 或者,您可以使用强制转换运算符添加显式转换:

        void initSetArray(set *setarray, int number_of_sets, int number_of_blocks) {
            setarray = (set*)malloc(sizeof(set) * (size_t)number_of_sets);
        }
        

      但是请注意,设置参数setarray 的值对用作initSetArray 参数的调用者变量没有影响。您应该返回指针或获取指向指针参数的指针。

      【讨论】:

        猜你喜欢
        • 2017-01-25
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        • 2010-10-23
        • 2016-02-04
        • 2021-11-08
        • 1970-01-01
        相关资源
        最近更新 更多