const变量赋值报错分析

const变量赋值报错

从变量到常量的赋值是合法C++的语法约定的,
如从char 到const char顺畅;
但从char **到 const char **编译器就会报错:

error: invalid conversion from `char**' to `const char**'

示例:

int main(int argc, char *argv[])
{
char a = '1';
const char b = a; char * a2 = "12345";
const char * b2 = a2; char** a3 = NULL; //const char** b3 = a3; //error
char** const c3 = a3; //ok
char* const * d3 = a3; //ok
}

原因:
const char** b3 说明 b3的指针可以变更,可以再指向另外一个地址;

b3和a3都是unqualified的,但b3指向的对象类型为pointer to const char,

a3指向的对象类型为 pointer to char,两者是不相容类型,

不符合两操作数必须指向相容类型的规定,因此赋值非法。

更详细的解释详见参考资料1;

而char** const c3 = a3;正确,则是因为const限制了c3指针的地址变更,即它指向了a3,就不再能变更指向其它指针了;这就限制了指针地址变更可能发生的潜在问题;

当然这时候,使用一个强制类型转换,可以解决这个编译错误:

    const char** b3 = const_cast<const char**>(a3); // ok

但转换后的代码再出现问题就很难排查了;

强制类型转换的潜在问题

看以下示例:

class Foo {
public:
Foo(){
i = 1;
}
void modify(){// make some modification to the this object
i = 2;
}
void print() const {
cout << "Foo_i:" << i << endl;
}
private:
int i;
}; //演示潜在的危险
//error: invalid conversion from `Foo**' to `const Foo**'
/////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
const Foo x;
Foo* p; //const Foo ** q = &p; //q now points to p; this is (fortunately!) an error
const Foo ** q = const_cast<const Foo **>(&p);
*q = &x; // p now points to x
p->modify(); // Ouch: modifies a const Foo!!
x.print(); // print: Foo_i:2
return 0;
}

我们定义了一个常量的Foo,常量Foo方法打印出来的永远为1;
Foo**到const Foo **的转换报错,

通过一个强转符让编译通过,

最后的x.print()的结果是2;这样的潜在危险在正式的项目代码中就很难发现;

很难会想到一个const对象还能够变更;

参考资料:

  1. 指针与const

  2. Why am I getting an error converting a Foo → Foo const?

  3. Converting Derived → Base works OK; why doesn't Derived → Base work?

const变量赋值报错分析的更多相关文章

  1. std::unique_ptr使用incomplete type的报错分析和解决

    Pimpl(Pointer to implementation)很多同学都不陌生,但是从原始指针升级到C++11的独占指针std::unique_ptr时,会遇到一个incomplete type的报 ...

  2. mysql5.7密码修改与报错分析

    1.修改密码 修改密码: vim /etc/my.cnf 的mysqld字段加入skip-grant-tables 重启MySQL,service mysqld restart 终端输入 mysql ...

  3. 微信小程序 app.js globalData 赋值报错

    //success方法要用用success: res => {}的格式 success: res => { } //赋值报错 success:function(e){ } //报错内容: ...

  4. Dev C++编写C/C++程序 出现[Error] ld returned 1 exit status报错分析及解决

    debug系列第一弹,不知道大家写程序的时候是不是都遇到过如题的报错. 我本人是经常遇到这行熟悉的令人不知所措的报错,可能是我太笨了 有时候百度无果也差不到原因,那就汇总一下目前我遇到的情况吧--持续 ...

  5. DUBBO报错分析—1(连接zookeeper成功,调用方法无反应,不报错)

    思路分析 调用方法时,最后调用执行的是mapper的sql语句,既然调用对应的方法无法获取返回值,多是sql错误,但是并未报sql错误,说明可能是与sql相关的数据源配置错误. 过程调试 经尝试,当直 ...

  6. SSM框架报错分析(一)——There is no getter for property named 'XXX' in 'class java.lang.String'

    一.发现问题 <select id="queryStudentByNum" resultType="student" parameterType=&quo ...

  7. 【原创】MySQL Can't create a new thread报错分析

    今天有两台服务器都出现了Can't create a new thread报错. [故障处理过程] 故障发生后登录服务器,检查mysql进程正常,但登录mysql报下面错误 ERROR 1135 (H ...

  8. SSH报错分析

    排错设计思路 1.配置文件的端口号修改 2.禁用root 3./etc/hosts.allow /etc/hosts.deny 4.iptables 5.密钥文件及目录的权限修改 1. 报错的原因:是 ...

  9. C++编译连接过程中关于符号表的报错分析

    是这样的,在学习郑莉老师的多文件结构和编译预处理命令章节时候,看到书里有这么一张图描述如下:#include指令作用是将指定的文件嵌入到当前源文件中#include指令所在的位置. 然后我就想5_10 ...

随机推荐

  1. android 应用架构随笔五(ActionBar与侧滑菜单DrawerLayout)

    ActionBar(V7)的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,在Androi ...

  2. SQL学习记录

    一些最重要的 SQL 命令 SELECT - 从数据库中提取数据 UPDATE - 更新数据库中的数据 DELETE - 从数据库中删除数据 INSERT INTO - 向数据库中插入新数据 CREA ...

  3. grd文件结构

  4. html5 canvas 笔记四(变形 Transformations)

    绘制复杂图形必不可少的方法 save() 保存 canvas 状态 restore() 恢复 canvas 状态 Canvas 的状态就是当前画面应用的所有样式和变形的一个快照. Canvas 的状态 ...

  5. Tutorial: WPF User Control for AX2012

    原作者: https://community.dynamics.com/ax/b/goshoom/archive/2011/10/06/tutorial-wpf-user-control-for-ax ...

  6. Microsoft Office 2013 Product Key

    Microsoft Office 2013 Product Key ( Professional Plus ) PGD67-JN23K-JGVWW-KTHP4-GXR9G B9GN2-DXXQC-9D ...

  7. iOS开发- 蓝牙后台接收数据(BLE4.0)

    最近在做一个蓝牙相关的项目, 需要在应用进入后台, 或者手机属于锁屏状态的情况下, 仍然保持蓝牙连接, 并且能正常接收数据. 本来以后会很麻烦, 但是学习了下..发现就2步而已.简单的不能再简单了. ...

  8. 使用pt-heartbeat检测主从复制延迟

    不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间,原因如下: A:备库Seconds_behand_master值是通过将服务器当前的时间戳与二进制日志中的事件的时间戳对 ...

  9. python: 字符串按空格分成列表split与加密密码maketrans

    #字符串按空格分成列表split() print("fu li mei".split()) #split按空格分成列表 print("1+a+2+b".spli ...

  10. css2---必须学的经典---定位问题

    定位 position body<html<文档  定位是相对文档的 不是相对 body 或 html 1.position:relative 相对定位 a.不能使内嵌元素支持宽高  b. ...