【问题标题】:In Xcode, I found semantic issue in the code snippet在 Xcode 中,我在代码片段中发现了语义问题
【发布时间】:2020-07-22 18:33:50
【问题描述】:

程序试图编译,但我发现错误显示,'control may reach end of non-void function'。我想在返回比较之后如何处理 if 条件。我一直在想如何解决这个问题。

   int compare(const void *a, const void *b)
  {
    if (*(int *)a < *(int *)b)
        return -1;
    if (*(int *)a == *(int *)b)
        return 0;
    if (*(int *)a > *(int *)b)
        return 1;
  }

【问题讨论】:

  • (a) 这只是一个警告,(b) 你的比较之一是多余的

标签: c++


【解决方案1】:

不应检测到“控件可能到达非空函数的结尾”,因为实际上不存在这种可能性。可能是数据流分析没有正确检测到这一点。

但是,有一个更好的替代方案可以实现这一点,它也可以解决您的问题:

int compare(const void *a, const void *b)
{
  return (*(const int*)b < *(const int*)a) - (*(const int*)a < *(const int*)b);
}

顺便说一句。此代码的性能更好,因为您不再需要任何分支。

一个用于演示的小型 MCVE:

#include <iostream>

int compare(const void *a, const void *b)
{
  return (*(const int*)b < *(const int*)a) - (*(const int*)a < *(const int*)b);
}

int main()
{
  int a = 1, b = 2;
  std::cout << "compare(&a, &b): " << compare(&a, &b) << '\n';
  std::cout << "compare(&b, &a): " << compare(&b, &a) << '\n';
  std::cout << "compare(&a, &a): " << compare(&a, &a) << '\n';
  return 0;
}

输出:

compare(&a, &b): -1
compare(&b, &a): 1
compare(&a, &a): 0

Live Demo on coliru

我必须承认,当我回答时,有人“强迫”我使用这个漂亮的比较技巧

SO: Sorting an array of integers in alternate fashion using qsort function..

这是我在那里给出的解释:

它是如何工作的:

如果a &lt; b(a &gt; b) - (a &lt; b)0 - 1-1

如果a == b(a &gt; b) - (a &lt; b)0 - 00

如果a &gt; b(a &gt; b) - (a &lt; b)1 - 01

【讨论】:

【解决方案2】:

不要在 C++ 中使用 C 风格的强制转换。

如您所知,您涵盖了所有条件,最后一个测试是多余的:

int compare(const void *a, const void *b)
{
int a1 = *static_cast<const int *>(a);
int b1 = *static_cast<const int *>(b);
if (a1 < b1)
    return -1;
if (a1 == b1)
    return 0;
return 1;
}

【讨论】:

    【解决方案3】:

    如果您不知道这些指针背后的对象的实际类型是什么,您可能需要这样做:

    #include <cstring>
    
    int f(const void *a, const void *b)
    {
        int ai;
        int bi;
        std::memcpy(&ai, a, sizeof(int));
        std::memcpy(&bi, b, sizeof(int));
        return (bi < ai) - (ai < bi);
    }
    

    【讨论】:

      【解决方案4】:

      这里的要点是编译器无法识别您的条件涵盖所有可能的情况。 => 如果您的条件都不满足,则函数在没有返回语句的情况下结束。你应该在这里使用 if - else if - else:

      if (…) { … }
      else if (…) { … }
      else { … }
      

      这将有助于编译器更好地理解您的代码。你放弃了一次条件。

      避免使用分支是个好主意,但通常以失去可读性为代价。查看@Scheff 对此的回答。

      【讨论】:

        猜你喜欢
        • 2018-12-16
        • 2018-03-03
        • 1970-01-01
        • 2012-12-16
        • 2011-08-20
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多