函数在不同的配置上返回不同的值
Function returning different values on different configuration
这是我的代码片段:
int fastcmp(const void* ptr1, const void* ptr2, size_t size)
{
if (ptr1 == ptr2) return 0;
if (!ptr1 || !ptr2) return -1;
size_t remain = size;
if (size >= 8)
{
remain = size % 8;
size_t work = size / 8 + 1;
auto p1 = (const uint64_t*) ((const uint8_t*)ptr1 + remain);
auto p2 = (const uint64_t*) ((const uint8_t*)ptr2 + remain);
while(--work > 0)
if(p1[work] != p2[work]) return -1;
}
auto p1 = (const uint8_t*) ptr1;
auto p2 = (const uint8_t*) ptr2;
while(remain-- > 0)
if (p1[remain] != p2[remain]) return -1;
return 0;
}
int main(int argc, char* argv[])
{
if (argc == 3)
{
size_t len1 = strlen(argv[1]);
size_t len2 = strlen(argv[2]);
if (len1 == len2)
{
std::cout << "fastcmp returns:" << fastcmp(argv[1], argv[2], len1) << std::endl;
std::cout << "memcmp returns:" << memcmp(argv[1], argv[2], len1) << std::endl;
}
}
return 0;
}
所以我在 vscode 中使用代码 运行ner 并在 mingw 中使用 g++。我设置 launch.json 两个参数完全相同。 运行 调试和函数 returns 0。之后我用 g++ 编译它并尝试 运行 使用终端 运行 使用我在 launch.json 中编写的相同参数。但是函数 returns 带有 -1。有人可以解释为什么吗?谢谢,这让我感到困惑。
fastcmp returns -1 if strlen > 8
g++ -std=c++11 foo.cpp -o foo
我不能马上告诉你为什么会这样,但有办法找出答案。
确定问题根源的核心问题是,许多分支return -1(我看到3)。我建议将其更改为不同的值,或添加一些日志记录语句。然后你可以检查触发它的条件。这可能与你所做的所有演员有关。
如果转换是问题所在,请考虑使用静态转换并放弃使用 c 风格的指针并切换到现代共享指针。 c++ 的现代扩展旨在使语言更清晰,在某些情况下使编译更具确定性。
在fastcmp中替换
即可
size_t work = size / 8 + 1;
来自
size_t work = size / 8;
和
while(--work > 0) {
来自
while(work-- != 0) {
否则您查看索引 n..1 而不是 n..0,因此您不会检测到 remain+0..7 个字符
中的差异
(注意 size_t
未签名)
请注意,您假设您可以从任何对齐方式读取 uint64_t,从偏移量 0 读取而不是 remain更安全(argv[i]
中的字符串对齐以与任何数字大小兼容),无论如何如评论中所述,您违反了严格的别名规则,并且您的行为差异是未定义行为的结果
这是我的代码片段:
int fastcmp(const void* ptr1, const void* ptr2, size_t size)
{
if (ptr1 == ptr2) return 0;
if (!ptr1 || !ptr2) return -1;
size_t remain = size;
if (size >= 8)
{
remain = size % 8;
size_t work = size / 8 + 1;
auto p1 = (const uint64_t*) ((const uint8_t*)ptr1 + remain);
auto p2 = (const uint64_t*) ((const uint8_t*)ptr2 + remain);
while(--work > 0)
if(p1[work] != p2[work]) return -1;
}
auto p1 = (const uint8_t*) ptr1;
auto p2 = (const uint8_t*) ptr2;
while(remain-- > 0)
if (p1[remain] != p2[remain]) return -1;
return 0;
}
int main(int argc, char* argv[])
{
if (argc == 3)
{
size_t len1 = strlen(argv[1]);
size_t len2 = strlen(argv[2]);
if (len1 == len2)
{
std::cout << "fastcmp returns:" << fastcmp(argv[1], argv[2], len1) << std::endl;
std::cout << "memcmp returns:" << memcmp(argv[1], argv[2], len1) << std::endl;
}
}
return 0;
}
所以我在 vscode 中使用代码 运行ner 并在 mingw 中使用 g++。我设置 launch.json 两个参数完全相同。 运行 调试和函数 returns 0。之后我用 g++ 编译它并尝试 运行 使用终端 运行 使用我在 launch.json 中编写的相同参数。但是函数 returns 带有 -1。有人可以解释为什么吗?谢谢,这让我感到困惑。
fastcmp returns -1 if strlen > 8
g++ -std=c++11 foo.cpp -o foo
我不能马上告诉你为什么会这样,但有办法找出答案。 确定问题根源的核心问题是,许多分支return -1(我看到3)。我建议将其更改为不同的值,或添加一些日志记录语句。然后你可以检查触发它的条件。这可能与你所做的所有演员有关。 如果转换是问题所在,请考虑使用静态转换并放弃使用 c 风格的指针并切换到现代共享指针。 c++ 的现代扩展旨在使语言更清晰,在某些情况下使编译更具确定性。
在fastcmp中替换
即可size_t work = size / 8 + 1;
来自
size_t work = size / 8;
和
while(--work > 0) {
来自
while(work-- != 0) {
否则您查看索引 n..1 而不是 n..0,因此您不会检测到 remain+0..7 个字符
中的差异(注意 size_t
未签名)
请注意,您假设您可以从任何对齐方式读取 uint64_t,从偏移量 0 读取而不是 remain更安全(argv[i]
中的字符串对齐以与任何数字大小兼容),无论如何如评论中所述,您违反了严格的别名规则,并且您的行为差异是未定义行为的结果