tracifycray
tracifycray

Reputation: 1423

Control may reach end of non-void function error if-statement

I'm getting the error Control may reach end of non-void function on this code:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (changeData.selectedSegmentIndex == 0) {
        return self.tweets.count;
    } else if (changeData.selectedSegmentIndex == 1) {
        return self.tweets1.count;
    } else if (changeData.selectedSegmentIndex == 2) {
        return self.tweets2.count;
    }
}

Why?

Upvotes: 3

Views: 5886

Answers (5)

Henadzi Rabkin
Henadzi Rabkin

Reputation: 7062

If you think its ok disable it:

enter image description here

Upvotes: 2

akim
akim

Reputation: 8759

While I agree with most answers that suggest to avoid multiple returns in the general, on occasions multiple returns is nice and useful. For instance dispatching on an enum:

#include <iostream>
#include <string>

enum direction { north, east, south, west };

std::string to_string(direction d)
{
  switch (d)
    {
#define CASE(C) case C: return #C
      CASE(north);
      CASE(east);
      CASE(south);
      CASE(west);
#undef CASE
    }
}

int main()
{
  std::cout << to_string(west) << '\n';
}

If you compile with GCC, you get (C or C++, it's the same):

$ g++-4.9 -Wall foo.cc
foo.cc: In function 'std::string to_string(direction)':
foo.cc:17:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

Clang does not complain. Which is not so nice, actually, since it also compiles this without warnings:

int main()
{
  std::cout << to_string(direction(666)) << '\n';
}

which results in:

$ clang++-3.5 -Wall foo.cc
$ ./a.out
zsh: illegal hardware instruction  ./a.out

So one has to "fight" GCC's warning. One wrong approach would be to add say

default:  abort();

to the switch. Sure, it cures the symptom, but now GCC will no longer complain if I add a new direction, say zenith, but forget to cover it in to_string. So really, never use a default case when switching on an enum.

Then you can leave an abort after the switch (which is clumsy to do without using inner returns).

Upvotes: 0

Suhit Patil
Suhit Patil

Reputation: 12023

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger count = 0;
    if (changeData.selectedSegmentIndex == 0) {
        count = self.tweets.count;
    } else if (changeData.selectedSegmentIndex == 1) {
        count = self.tweets1.count;
    } else {
        count = self.tweets2.count;
    }
   return count;
}

or

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
   {
         NSInteger count = 0;
     if (changeData.selectedSegmentIndex == 0) {
        count = self.tweets.count;
     } else if (changeData.selectedSegmentIndex == 1) {
        count = self.tweets1.count;
     } 
     else if (changeData.selectedSegmentIndex == 2){
            count =  self.tweets2.count;
     }
     return count;
   }

Upvotes: 0

T. Benjamin Larsen
T. Benjamin Larsen

Reputation: 6393

Midhun MP has your answer and better code style. I would strongly advice replacing all those nested else-ifs with a switch-statement as, well you don't really want else-ifs if you can avoid them...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
       NSInteger count = 0;
       switch (changeData.selectedSegmentIndex) 
            {
           case 0:
               count = self.tweets.count;
               break;
           case 1:
               count = self.tweets1.count;
               break;
           case 2:
               count = self.tweets2.count;
               break;
           default:
               break;
            }
    return count;
}

Upvotes: 2

Midhun MP
Midhun MP

Reputation: 107131

Because when your all if condition fails, you are not returning anything from the function.

Also multiple return statement in a function is not a good practice.

Do it like:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int count = 0;
    if (changeData.selectedSegmentIndex == 0)
    {
        count = self.tweets.count;
    }
    elset if (changeData.selectedSegmentIndex == 1)
    {
        count  = self.tweets1.count;
    }
    else if (changeData.selectedSegmentIndex == 2)
    {
        count  = self.tweets2.count;
    }
    return count;
}

Upvotes: 6

Related Questions