Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 为什么这个街区不是全球性的?_Objective C_Objective C Blocks - Fatal编程技术网

Objective c 为什么这个街区不是全球性的?

Objective c 为什么这个街区不是全球性的?,objective-c,objective-c-blocks,Objective C,Objective C Blocks,考虑以下代码: #include <stdio.h> typedef void (^block)(); block foo() { char a = 'a'; return [^{ printf("%c\n", a); } copy]; } block bar() { const char a = 'a'; return [^{ printf("%c\n", a); } copy]; } 让我困惑的是,第一个块不是全局块。它是一个堆栈块

考虑以下代码:

#include <stdio.h>

typedef void (^block)();

block foo() {
  char a = 'a';
  return [^{
    printf("%c\n", a);
  } copy];
}

block bar() {
  const char a = 'a';
  return [^{
    printf("%c\n", a);
  } copy];
}
让我困惑的是,第一个块不是全局块。它是一个堆栈块,然后被复制。这对我来说没有意义。编译器为什么不能自动推断出
a
实际上可以被视为
const
,这是我在C标准中忽略的吗

我正在构建这个
Os
,启用了ARC,下面是我的clang版本:

$ clang -v
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix

声明
char a
需要存储,这意味着
foo
中的块需要自己的变量
a
,该变量被初始化为
foo
a
值。块的变量存储在其“环境”中

声明
const char a
不需要分配存储,除非采用
a
的地址(根据C语言规范)。任何使用
a
的值都可以直接用其常量值代替。这意味着可以在没有任何环境的情况下编译
bar

因此,这两个块的编译方式不同


从理论上讲,如果语言规范不允许,编译器可能会检查变量的声明和使用,确定它在外部不可见,确定它的值在初始赋值后从未更改,并且它的地址从未被获取,然后用常量值替换变量。。。但这可能是一个很小的回报(如果有的话)的大量分析。

我不认为它不能,我认为它不够聪明。如果将块替换为更简单的内容(例如
返回a+1),会发生什么情况?可能只是错过了一个优化机会。你应该提交一份错误报告。@GregParker yeh如果我知道这肯定是一个错过的乐观主义者机会,我会提交一份大报告。@Sulthan说得不错。这肯定会直接返回“b”。错过了机会。是的,这一切都是有道理的——我只是希望乐观主义者会进行优化。我知道它不必这样做,但这仅仅是因为它没有这样做,还是标准中有某种原因意味着它不能这样做?我猜前者是对的?这里的回报相当大。查看生成代码中的差异。此外,在全局块情况下不需要块拷贝。这可能是一个重大改进。这是否可能发生是另一回事。@mattjgalloway-据我所知,C语言规范中没有任何东西会阻止这种优化。问题是它是否值得,如果不研究叮当声的来源,我们就不能说;我可以理解为什么在这种情况下没有这样做的原因(如果你去掉块,只是
printf
一个非常量var,var就会被省略)。但为什么不把它作为一个潜在的优化机会提交给苹果的Bug记者呢?它不会造成任何伤害。已提交是:-)。我只是想先看看这里,以防我发疯。我也想不出为什么它不能被优化。谢谢你的评论!你是否可以编辑你的答案,以表明它可以被优化,但这只是因为乐观主义者没有这样做。我会接受的。
$ clang -v
Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix