我可以在Objective-C switch语句中声明变量吗?

JoB*_*324 57 objective-c switch-statement

我想我会失明,因为我无法弄清楚此代码中语法错误的位置:

if( cell == nil ) {
    titledCell = [ [ [ TitledCell alloc ] initWithFrame:CGRectZero
        reuseIdentifier:CellIdentifier ] autorelease
    ];

    switch( cellNumber ) {
        case 1:
            NSString *viewDataKey = @"Name";
etc...
Run Code Online (Sandbox Code Playgroud)

当我尝试编译它时,我在最后一行的'*'标记之前收到错误:语法错误.

对不起这个基本问题,但我错过了什么?

eph*_*ent 69

我手边没有合适的Objective-C编译器,但只要C构造相同:

switch { … }为您提供一个块级范围,而不是每个范围case.在范围的开头以外的任何地方声明变量是非法的,并且在a switch特别危险,因为它的初始化可能会被跳过.

请执行以下任一方法解决问题?

NSString *viewDataKey;
switch (cellNumber) {
    case 1:
        viewDataKey = @"Name";
    …
}

switch (cellNumber) {
    case 1: {
        NSString *viewDataKey = @"Name";
        …
    }
    …
}
Run Code Online (Sandbox Code Playgroud)

  • wrt /`在范围的开头以外的任何地方声明变量是非法的.在C99中并非如此.C99都允许这样做并定义"控制跳过声明"时发生的事件的语义以及在这种情况下该声明的值. (2认同)

Chu*_*uck 20

您不能在case语句的开头声明变量.制作一个仅包含该测试用例的测试用例,您将得到相同的错误.

它与在块中间声明的变量无关 - 即使采用允许GCC在case语句开头接受声明的标准也是如此.看来GCC将案例标签视为该行的一部分,因此不允许在那里进行声明.

一个简单的解决方法就是在案例的开头添加一个分号,因此声明不在开头.

  • 这个答案的海报是正确的.问题的根源在于C99 BNF语法,它(松散地)将标记语句定义为:`...:statement`.简而言之,没有办法从`statement`到`declaration`.`compound-statement`(即`{...}`)(松散地)将`...`部分定义为`零个或多个块项`,块项(松散地)定义为`语句或声明`.此外,@ Dan Olson的评论都是错误的,不适用于C99,它非常清楚地定义了混合声明和语句wrt/initialization(C99 6.8.6.1等)的语义. (6认同)