当class遇上union

今天同事又踩到一个以前设计时留下的坑,这次是关于union和class中的。 虽然这种设计我并不认同, 但是至少我觉得设计者对于c++的成员内存布局相当了解。 由于面向对象的存在, 在代码中常常有这样一种用于存储属性的类,类A,类B, 类C,类B继承自类A,类C继承自类B。 而类A, 类B, 类C等这些类的实例都是从socket层传过来的。 作者在设计时为了代码的复用性, 采用了如下设计: union object { class A a; class B b; class C ……

权限问题引发的bug

大清早还在睡着, 被电话叫出来说软件出问题了T_T, 说软件不能解析某个文件. 软件挑文件这毛病还从没遇到过, 先把管理员权限, 文件路径是否存在等问题全部确认后没有发现异常. 万般无奈情况下, 荒谬的猜测代码打开文件时要求了写权限(如:fopen(file_path, “rb+”)), 而这个文件恰好被设置了只读属性, 会导致打开失败, 打开代码一看果然如此, 使用CreateFile, 但是却带有GENERIC_WRITE权限的要求. 发一下牢骚 🙂 这其实是一个典型的权限问题, 在此之前曾经碰到过, 在Win7以……

一个类型提升的bug

今天碰到一个由于类型提升的bug, 即使找到bug后, 仍花了好大功夫才找到解释, 感觉此坑比较隐蔽, 在此小记一下. 有类似下面一段代码: unsigned char a; unsigned char b; a = -1; b = 0; if (a == b - 1) printf("equal"); else printf("not equal"); 理论上当a为-1, b为0时应该打印出equal. 可事实恰恰相反, 打印出来的是not equal. C语言中有以下类型提升规则: 2. 一般常数为int型 1. 二元操作符如果两个操作数具有不同的类型, 那么将较低的类型提升为较高的类型……

多线程调DLL

最近写代码一不小心又着了多线程的道, 背景如下: 前不久写了这样一个DLL: const wchar_t *a = L"xxxx"; const wchar_t *b = L"xxxx"; int do_something_a(struct axx *param_a) { ... } int do_something_b(struct bxx *param_b) { ... } 在do_something_a与do_something_b中分别用到了字符串a, b.本来这样相安无事, 可是很多地方会用到这个DLL的代码, 但是字符串a, b并不一样, 而字符中a, b可以根据param_a, param_b中的信息来生成, 本着代码正交性的原则, 将DLL……

一个变量引发的血案

左天提交了代码, 大致测一下, 看起来来都OK啦. 今天准备放出去呢, 结果一来就各种不正常, 程序直接乱崩, Firmware各种跑死, 等等各种现象层出不穷. 所以今天可以是称为史上最悲剧的一天啦, 还是说原因吧, 希望以后不要再犯. ————————————————————————– 在之前的软件中使用了类似这样一个结构体: struct a { int ……

由于滥用void *引发的bug

我一向认为在写代码时,void *滥用是有问题的,在最近的一次代码中, 有类似这样一段代码:   [cc lang=”C”]int send(void *buff, unsigned long size); int xx_func(char *buff, unsigned long size) { unsigned send_size; ……… send(&buff, send_size); return 0; }[/cc] 暂且不论为什么作者会错写成取地址,但其原意是想发送经过处理后的buff里面的内容, 但是编译器是不会报错的,因为void *默认兼容所有类型,如果把代码改成下面这样:……

一次手误引出的bug

  在工作中写了这样一段代码: 1 struct xx_param { 2 int index1; 3 int index2; 4 }; 5 6 //func1, func2, func3为三个函数指针 7 8 int init(a_func_t *func1, b_func_t *func2, c_func_t *func3, void *param) 9 { 10 struct xx_param *p = (struct xx_param *)param; 11 func1(p->index1, p->index2); 12 } 13 14 int prepare_init(int xx_index_1, int xx_index_2) 15 { 16 int err; 17 struct xx_param ……

类似sprintf这类变参可能出现的bug

  中午吃完饭照例去云风大神的blog上去逛一圈,果然有新发现,如题: 1     char buff[3]; 2     char data; 3     sprintf(buff, "%02x", data);   咋一看,data最大等于0xff应该不会错,可以如果编译器默认char为signed char,而且data = -1,以十六进制看应该为0xff,这么看也没有错。   关键在于变参,在C语言的变参中,小于int长度的数据压栈时一律扩展为int型, 那么问题来了,符号型数据在进行类型扩展时是会扩展符号的,这么看其实 data = -1; sprintf(b……