我在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应该没问题,为什么会出现这个错误?
答案 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);
}