Variable declaration in switch-case
Welcome back to Objective C-land! Last week, I doubted my own sanity more than once. One day, for example, I refactored some code to use an enum and I nearly dispaired on a simple switch-case, until I reminded myself that I've stumbled over this issue quite a while ago. But back then, I didn't write it down. Time to change this!
tl;dr: You need to open a new scope, just use curly brackets.
Happy New Year everyone! Let's start with an enum:
typedef NS_ENUM(NSInteger, Weekday) {
WeekdayMonday,
WeekdayTuesday,
WeekdayWednesday,
WeekdayThursday,
WeekdayFriday,
WeekdaySaturday,
WeekdaySunday
};
Let's say, that I want to know, if I can have a beer on the evening of that day. So, let's write a method for that:
- (BOOL)iCanHazBeerOnWeekday:(Weekday)weekday {
BOOL iCanHazBeer = NO;
switch (weekday) {
case WeekdayFriday:
case WeekdaySaturday:
NSString *cheers;
cheers = @"Cheers! 🍻" // could be in one line
NSLog(cheers);
iCanHazBeer = YES;
break;
default:
iCanHazBeer = NO;
break;
}
return iCanHazBeer;
}
Everthing looks fine. But the code won't compile and Xcode complains on NSString *cheers
:
Expected expression
Past-me was too self-confident: Well, this is way too easy, I don't need to stack-overflow this thing. It must be some obvious, I can solve it on my own! A variable declaration is a expression, isn't it? WHAT'S WRONG WITH U xCODE?
After some time, it came to my mind, that I saw this exact same issue a while ago: Last time, I had to use curly brackets to make it work, similar to this one:
- (BOOL)iCanHazBeerOnWeekday:(Weekday)weekday {
BOOL iCanHazBeer = NO;
switch (weekday) {
case WeekdayFriday:
case WeekdaySaturday:
{
NSString *cheers;
cheers = @"Cheers! 🍻"
NSLog(cheers);
iCanHazBeer = YES;
}
break;
default:
iCanHazBeer = NO;
break;
}
return iCanHazBeer;
}
This looks weird, but due to syntactic constraints, a label can't be followed by a declaration. A better explanation is given on Stack Overflow: case
uses labels and in C, after a label, there has to be an expression — god knows why. And as an declaration isn't an expression, the compiler complains. This time, you can't blame ObjC, but C.
The workaround is to open a new scope and this way I can declare my variable right after a label. Well, okay, after the curly bracket after the label. But in the end, the workaround does its job — and it works.
Here you can find a a full reference for C, the relevant chapters are 6.7. Declarations and 6.8 Statements and blocks. Thank you again, Stack Overflow!
And thanks to you for reading this.