/ objectivec

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.

Variable declaration in switch-case
Share this