【问题标题】:Assigning pointers of different types分配不同类型的指针
【发布时间】:2021-04-26 09:23:45
【问题描述】:

为什么lp的初始化是非法的?

int i = 42; 
long *lp = &i;

Xcode 提示我不能用'int *' 类型的右值初始化'long *' 类型的变量。

为什么?

【问题讨论】:

  • 指针就是它所说的,它指向某个对象,对象类型在指针的声明中说,如果你有long *类型的变量,它必须有long类型的地址目的。在继承和类的情况下,情况并非总是如此,但对于内置类型,它是。

标签: c++ pointers


【解决方案1】:

你的Xcode是对的,它们是不同的类型,确实是非法初始化,C++不允许分配(或初始化)不同类型的指针。

也就是说,您可以显式转换受让人:

int i = 42; 
long *lp = reinterpret_cast<long*>(&i);

关于你的推理,我会说这些是语言的规则,它们是为了保护你(和你的程序),而不是让你的工作更困难,指向 long 的指针用于操作(取消引用、递增等)在用于存储 int 的地址中将调用未定义的行为。编译器没有义务以相同的方式处理不同类型的指针。可能会出现大小、对齐方式等方面的差异。

As largest_prime_is_463035818 stated 明确转换的义务试图防止错误。

然而,这只允许你编译你的程序,它并不能消除它的格式错误的可能性。

Simple example:

int i = 42;   

int *p = &i;    
long *lp = reinterpret_cast<long*>(&i);
long *lpc = (long*)(&i); 

std::cout << "int pointer => " << *p << "\n";   // fine, prints 42
std::cout << "long pointer => " << *lp << "\n"; // not fine, prints random vaue *
std::cout << "long pointer 2 => " << *lpc << "\n"; // not fine, same *

正如您在上面的示例中看到的那样,您的编译器是正确的,这确实是一个有问题的转换,欺骗编译器允许转换使程序编译,但未能产生一致的结果。

*我也在windows平台上试过,效果不错,可能是因为我平台的long只有4个字节,和int一样,可能不是,重点是,你只有当您绝对确定类型是可互换的时,应该这样做。

【讨论】:

  • 我想知道为什么lp的初始化是非法的?是什么原因,原理是什么?
  • @ChenglongLi 反问:为什么要允许?如果您想将int* 分配给long*,那么很有可能您将其中一个声明为错误类型,或者您的代码中有逻辑错误。强制您通过强制转换使其显式有助于避免错误,它将逻辑错误或拼写错误转化为编译器错误,这通常是可取的
  • @ChenglongLi,这些是规则,它们可以保护您(和您的程序),指向 long 的指针用于在用于存储 int 的地址中进行操作可能会导致未定义的行为,编译器没有义务以相同的方式处理不同类型的指针。作为 maximum_prime_is_463035818 的显式转换确保不会出错,此外使用 reinterpret_cast 添加了额外的保护层,只能执行允许的转换。
  • @ChenglongLi 虽然不是同一个主题,你可以在这里找到一些有用的信息stackoverflow.com/q/19710601/6865932
  • @ChenglongLi 即使编译器允许这样的赋值,intlong 是不同的类型并且不能保证大小相同,所以尝试通过@987654336 访问int @ 指针,或通过 int* 指针访问 long,将是未定义的行为
猜你喜欢
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多