【问题标题】:code snippet warning: cast to pointer from integer of different size代码片段警告:从不同大小的整数转换为指针
【发布时间】:2014-05-21 11:39:41
【问题描述】:

在下面的代码 sn-p 中,我收到此警告 - 第 25 行中的“警告:从不同大小的整数转换为指针” 这是我做的第三次打印,

printf("value of a thru struct ptr=%d\n",(unsigned char *)m_arr(ptr_ns_type)[0]);

我不明白这个警告,因为我在第二个 printf 中做了同样的事情(除了不使用宏)

printf("value of a thru ptr=%d\n",(unsigned char)*ptr);

我没有得到任何错误。谁能帮我理解这个警告吗?

谢谢, 巴德里。

#include<stdio.h>
struct ns
{
    int i;
    unsigned char a[2];
};
#define m_arr(whatever)         ((struct ns *)whatever)->a
int main()
{
    unsigned char arr[2];  
    unsigned char brr[2]; 
    struct ns ns_type;
    struct ns *ptr_ns_type;
    arr[0]=192;
    arr[1]=168;
    brr[0]=172;
    brr[1]=188;

    ns_type.i=5;
    ns_type.a[0]=brr[0];
    ptr_ns_type = &ns_type;
    unsigned char *ptr=arr;
    printf("value of a=%d\n",arr[0]);
    printf("value of a thru ptr=%d\n",(unsigned char)*ptr);
    printf("value of a thru struct ptr=%d\n",(unsigned char *)m_arr(ptr_ns_type)[0]);
    return 0;
}

【问题讨论】:

  • 一次做一件事,你的代码会变得更清晰,更容易修复。

标签: c pointers


【解决方案1】:

这里不需要演员表:

printf("value of a thru ptr=%d\n",(unsigned char)*ptr);

因为ptr 是指向unsigned char 的指针,所以*ptr 已经是unsigned char

但是,这里:

(unsigned char *)m_arr(ptr_ns_type)[0]

翻译成:

(unsigned char *)((struct ns *)ptr_ns_type)->a[0]

您正在尝试将unsigned char 转换为指向unsigned char 的指针。我想你想要的是:

((struct ns *)ptr_ns_type)->a[0]

但也请注意,(struct ns *) 演员表不是必需的。

【讨论】:

  • 非常感谢 perreal.. 现在明白了。
  • perreal - 只是好奇。为什么将“unsigned char 转换为指向 unsigned char 的指针”未标记为错误?为什么只是一个警告?
  • 因为指向 unsigned char 的指针比 unsigned char 大,也因为强制转换是显式的,这意味着程序员强制它并且编译器必须遵守。
【解决方案2】:

实际上,您根本没有做同样的事情。尝试通过手动进行文本替换来摆脱宏。例如,让我们创建一个类型为 unsigned char* 的变量 tmp:

unsigned char* tmp1 = (unsigned char *)       ((struct ns *)ptr_ns_type)->a[0];

您将收到相同的警告。所以宏与它无关。此外,强制转换为 struct ns * 是多余的和邪恶的,因为它删除了有价值的类型检查。所以我们可以去掉它以获得更清晰的代码:

unsigned char* tmp1 = (unsigned char *)       ptr_ns_type->a[0];

当然,您仍然会得到完全正确的警告,但希望现在清楚发生了什么。当你调用ptr_ns_type->a[0]时,你是在解引用ptr_ns_type来获取数组a,并使用[]操作符来获取a[0]的value,这是一个无符号字符,而不是指向无符号字符的指针。

如果要获取a[0]的地址,可以省略[0]操作:

unsigned char* tmp1 = (unsigned char *) ptr_ns_type->a;

我认为这是一个练习,可以帮助您理解指针、数组、宏和强制转换的要点。请学习以下课程: 1. 宏是邪恶的。仅当它们增加代码的清晰度时才使用它们。 2.避免不必要的铸造。这是不安全的。 3.简化,简化。一旦我们简化了有问题的代码,错误就变得很明显了。

【讨论】:

  • 太空驼鹿——太棒了。感谢您努力解释。是的,我正在查看大量代码中的警告,并尝试用较小的程序来理解。
猜你喜欢
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 2014-02-14
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多