以前可能已经以其他方式提出了这个问题(如果不是这样的话,我会感到惊讶),但是我很难找到它。
鉴于:

#include <iostream>
#include <string>

int main()
{
    int * const pi = new int(1);
    long int * const pl = reinterpret_cast<long int * const>(pi);
    std::cout << "val: " << *pl << std::endl;
    return 0;
}

我得到警告:
<source>: In function 'int main()':
<source>:7:27: warning: type qualifiers ignored on cast result type [-Wignored-qualifiers]
    7 |     long int * const pl = reinterpret_cast<long int * const>(pi);
      |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ASM generation compiler returned: 0
<source>: In function 'int main()':
<source>:7:27: warning: type qualifiers ignored on cast result type [-Wignored-qualifiers]
    7 |     long int * const pl = reinterpret_cast<long int * const>(pi);
      |                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Execution build compiler returned: 0
Program returned: 0
val: 1
但我不确定为什么会收到此警告,因为重铸也应该是const指针-只是指向其他类型。我想实现相同的代码(如果忽略警告,则可以使用),但是没有警告。

最佳答案

long int * const是指向可变数据的不变指针。reinterpret_cast返回一个临时对象。在大多数临时对象(包括该对象)上,顶级类型的不变性无关紧要。
这个:

long int * const pl = reinterpret_cast<long int * const>(pi);
是相同的
long int * const pl = reinterpret_cast<long int *>(pi);
编译器会警告您,因为大概您认为在输入const做了,但是您错了,它什么也没做。

现在,这与您的要求没有直接关系,但是如果我不提这一点,我将不为所动:
std::cout << "val: " << *pl << std::endl;
导致您的程序表现出不确定的行为。指向的对象不是long int,它是int,并且您以其类型不是该对象的对象来访问它。reinterpret_cast并不是“将这些字节当作另一种类型来对待”,尽管许多人都将其视为正确。在C++标准下,此类操作几乎总是未定义的行为。
将对象A的字节解释为类型B的对象(当它们是普通类型时)的正确方法是使用memcpy之类的东西。
int * const pi = new int(1);
long int l = 0;
static_assert( sizeof(*pi) == sizeof(l) );
::memcpy( &l, pi, sizeof(l) ); // or l = std::bit_cast<long int>(*pi) in C++20
std::cout << "val: " << l << std::endl;
如果实现定义了输出,这是合法的,因为您可以随意复制足够琐碎的类型的字节,并且long int必须没有陷阱值。

在C++中,没有合法的方法来将一块内存同时作为long intint进行读取/写入。允许在C++中使用别名(将一种类型当作另一种类型)的数量是有限的,因为违反别名会使某些真正强大的优化变得不可能或不切实际。
当您执行此类操作时,许多程序会忽略此事实,而是依靠编译器生成“天真的”程序集。他们正在生成表现出未定义行为的代码。

关于c++ - 将int * const强制转换为long int * const警告,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/64246999/

10-11 22:40
查看更多