无法从XXX**转换为常量XXX**

Cannot convert from XXX** to const XXX**

本文关键字:XXX 常量 转换      更新时间:2023-10-16

我用c++编写了非常简单的代码。当我在Visual studio下编译时,会发生错误。

#include <stdint.h>
#include <time.h>
void func1(const uint8_t* data)
{
}
void func2(const uint8_t** data)
{
}
int main() 
{
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);//OK
func2(data2);//error C2664: cannot convert argument 1 from 'uint8_t **' to 'const uint8_t **'
}

完整的错误信息是:

错误C2664:"void func2(const uint8_t**)":无法将参数1从"uint8_t**"转换为"const uint8_t**">

通常你不能将常量XXX转换为XXX,但从XXX转换为常量XXX应该是可以的,为什么这里会发生这种错误?

但从XXX到常量XXX应该是OK

不,这在这个特定的实例中是不好的。考虑:

int const x = 10; // implementation stores to read-only memory
// implementation crashes on writes to read-only memory
void foo(int const **ptr) {
*ptr = &x;
}
int main() {
int *p;
foo(&p);
*p = 12; // crash
}

如果这是合法的,它会将"指针到常量"值分配给"指针到非常量"对象,从而导致对常量对象的危险写入。

要想转换为const,必须在上面类型中添加最低const的每个级别添加const(最顶部除外)。

例如,将int ******转换为int ***const***是不可以的,但将其转换为int ***const*const*const*是可以的。这也适用于volatile:您可以将int ******转换为int ***volatile*const*const*,但不能将int ***volatile***转换为

类型系统中的这条规则可以防止我们错误地将常量对象视为非常量,或将易失性对象视为不易失性,如果我们真的想犯这个错误,那么我们必须使用const_cast

foo(const_cast<int const **>(&p));
*p = 12; // crash

有了const强制转换,程序的格式就很好了,编译器很乐意生成一个表现出未定义行为的可执行文件。(实例)


修复foo()以允许其获取指向非常量的指针:

void foo(int const * const *ptr) {
*ptr = &x; // error, can't modify *ptr 
}
foo(&p); // conversion works fine

阻止foo()将"指向常量的指针"值写入"指向非常量的指针"对象。(实例)


您可能认为XXX到const XXX是可以的,因为最常见的情况是,对于单级指针:int *->int const *可以的,并且也遵守上述转换规则。最高层的const并不重要,因为对参数本身的更改不会脱离函数。

当使用指针的指针常量时,需要使用uint8_t const* const*

#include <stdint.h>
#include <time.h>
void func1(const uint8_t* data) { 
}
void func2( uint8_t const* const* data ) {
}
int main() {
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);//OK
func2(data2);
}

这是您的两个选项,这个。。。

void func1(const uint8_t* data)
{
}
void func2(const uint8_t** data)
{
}
int main() 
{
const uint8_t* data1 = NULL;
const uint8_t** data2 = NULL;
func1(data1);
func2(data2);
}

或者这个。。。

void func1(uint8_t* data)
{
}
void func2(uint8_t** data)
{
}
int main() 
{
uint8_t* data1 = NULL;
uint8_t** data2 = NULL;
func1(data1);
func2(data2);
}