无法从XXX **转换为const XXX **

时间:2014-02-12 18:19:07

标签: c++ visual-studio

我在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 **'

通常你不能将const XXX转换为XXX,但是从XXX到const XXX应该没问题,为什么会出现这个错误?

3 个答案:

答案 0 :(得分:7)

  

但从XXX到const XXX应该没问题

不,在这个特定的例子中这不可行。考虑:

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,可以将const添加到上面添加最低const的类型中的每个级别(除了最顶层)。

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

类型系统中的这个规则保护我们不会错误地将const对象视为非const,或者将volatile对象视为非易失性,如果我们真的想犯这个错误,那么我们必须使用const_cast。< / p>

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

使用const转换程序很好,编译器很乐意生成一个展示未定义行为的可执行文件。 (live example


修复foo()以允许它获取指向非const的指针:

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

foo(&p); // conversion works fine

阻止foo()将'const'值的指针写入'指向非const'对象的指针。 (live example


你可能认为XXX到const XXX是可以的,因为这是最常见的情况,即单级指针:int * - &gt; int const * 没法,并且还遵守上述转换规则。最高级别的const无关紧要,因为参数本身的更改不会转义函数。

答案 1 :(得分:3)

当你使用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);
}

答案 2 :(得分:0)

以下是您的两个选择,这...

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);
}