问题描述
当我编写代码时,我创建的更常见的错误类别是一对一错误 (OBO)。在“真实”代码中,我在用 C 或 C++ 进行复杂的指针/迭代器算术时最常遇到这个问题,但有时我在面试和家庭作业(例如实现合并排序)问题中也遇到了问题,我使用了其他编程语言。
我的典型调试策略包括随机交换 <
和 <=
、++var
和 var++
并将 + 1
或 - 1
附加到变量,直到该代码似乎有效。我很想知道存在哪些更好的策略或工具(例如静态分析、调试器/IDE 功能等)来发现 OBO。
我对诸如“避免 C 风格的循环”、“避免指针算术”、“以函数式风格编写代码”或“使用不同的编程语言”之类的 pat 答案并不特别感兴趣。是的,这些事情可以缓解这个问题,但并不总是可行的,而且它们也不能完全消除 OBO 的危险。
举个例子,我相信下面的代码,strcpy(3)
的 C(或者它也是有效的 C++)实现,没有 OBO。但是正如您所看到的,OBO 可能会出现许多潜在的问题领域。有什么方法可以轻松确认它实际上没有 OBO 吗?
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(X)
#endif
#ifdef __cplusplus
extern "C" {
#if defined(__GNUC__) || defined(_MSC_VER) || defined(__restrict)
#define restrict __restrict
#elif !defined(restrict)
#define restrict
#endif
#endif
static inline bool aligned8(const void *ptr) {return !((uintptr_t)ptr & 7);}
static inline bool aligned4(const void *ptr) {return !((uintptr_t)ptr & 3);}
static inline bool aligned2(const void *ptr) {return !((uintptr_t)ptr & 1);}
/* Positive return value is the greatest common alignment (≤8) of the pointers.
* Negative return value is the byte offset that when added to both pointers
* yields a pair of pointers with alignment ≥8.
*/
static inline int common_alignment(const void *p1,const void *p2) {
if (aligned8(p1)) {
if (aligned8(p2))
return 8;
else if (aligned4(p2))
return 4;
else if (aligned2(p2))
return 2;
} else if (aligned4(p1)) {
if (aligned8(p2))
return 4;
else if (aligned4(p2))
return -4;
else if (aligned2(p2))
return 2;
} else if (aligned2(p1)) {
if (aligned4(p2))
return 2;
else if (aligned2(p2))
return -6;
} else if (!aligned2(p2)) {
return -7;
}
return 1;
}
/* strcpy implementation
*/
__attribute__((nonnull))
size_t string_copy(char *restrict dst,const char *restrict src) {
size_t i = 0;
int align = common_alignment(dst,src);
if (align < 0) {
for (; i < (size_t)-align; ++i)
if (!(*dst++ = *src++))
return i;
align = 8;
}
const size_t mask = (size_t)align - 1;
#define ALIGNED_STRING_copY_IMPL_(BITS) do {\
uint##BITS##_t *restrict dst##BITS = (uint##BITS##_t*)dst;\
while (*src++)\
if (!(++i & mask))\
*dst##BITS++ = *(const uint##BITS##_t *restrict)(src - align);\
dst = (char*)dst##BITS;\
} while (0)
if (align & 8) {
ALIGNED_STRING_copY_IMPL_(64);
} else if (align & 4) {
ALIGNED_STRING_copY_IMPL_(32);
} else if (align & 2) {
ALIGNED_STRING_copY_IMPL_(16);
} else { // byte-aligned
while ((*dst++ = *src++))
++i;
return i;
}
const size_t offset = (i & mask) + 1;
memcpy(dst,src - offset,offset);
return i;
}
#ifdef __cplusplus
}
#endif
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)