关于 Objective-C 中没有主体的“for”循环的奇怪编译器优化/行为

问题描述 投票:0回答:2

我有以下 C 数组

NSString *
:

static NSString *const OrderByValueNames[] = {@"None",@"Added",@"Views",@"Rating",@"ABC",@"Meta"};

现在,我想在运行时检查这个数组的长度,所以我编写了以下方法:

NSInteger LengthOfArray(NSString *const array[])
{
    NSInteger length = 0;
    // For Loop Without a body!
    for (length = 0; array[length] != nil; length++);
    return length;
}

现在,当我在

debug
配置下运行此代码时,一切都很好,并且该函数返回正确的结果。

但是一旦我切换到

release
配置并再次运行它,程序就会冻结在for循环中。循环执行 10 秒后,iOS 会因应用程序没有响应而终止该应用程序。奇怪。

现在,如果我将主体添加到循环中,就像这样:

for (length = 0; array[length] != nil; length++)
{
    NSLog(@"%d",length);
}

然后它就可以正常工作了即使在发布模式下

给循环一个空体,就像这样:

for (length = 0; array[length] != nil; length++){}

在释放模式下仍然冻结。

我的猜测是在发布模式下运行时有编译器优化,但到底是什么?!

有什么想法吗?

arrays c objective-c for-loop compiler-optimization
2个回答
10
投票

C 风格的数组默认不是以 nil 结尾的。如果你想通过这种方式检查长度,你需要自己添加终止符。

static NSString *const OrderByValueNames[] =
   {@"None",@"Added",@"Views",@"Rating",@"ABC",@"Meta",nil};

找到长度的更好方法就是这样:

length = sizeof(OrderByValueNames) / sizeof(OrderByValueNames[0]);

(请注意,如果将数组传递给函数,则此技巧不起作用,因为它会退化为指针。)


6
投票

您的

OrderByValueNames
数组不包含
nil
元素。难怪你找不到!像这样离开数组的末尾将导致未定义的行为。如果您想用
nil
标记数组的末尾,则必须手动添加。

顺便说一句,如果你想知道固定大小的 C 数组的长度,你可以这样做:

length = sizeof(OrderByValueNames)/sizeof(OrderByValueNames[0]);

但这不适用于函数参数,因为它们只是指针!

© www.soinside.com 2019 - 2024. All rights reserved.