3

以下代码编译:

^{}();

这编译:

void (^x)();
(x = ^{})();

但这不会:

(void (^x)() = ^{})();

我得到的错误是Expected ')'. 这是llvm的错误还是什么?它完全阻止了我假装 Objective-C 是 JavaScript。

4

2 回答 2

6

这在类 C 语言中是没有意义的。要了解原因,让我们从头开始构建语句。

首先,我们将您的工作声明用于x

void (^x)();

现在让我们在同一个语句中初始化它:

void (^x)() = ^{};

到目前为止一切顺利 -x已使用正确的块进行初始化。所以让我们现在调用x。但是会()去哪里呢?自然,我们需要将()立即放在块值表达式之后。但是,在 C 中,声明是语句,而不是表达式,所以

(void (^x)() = ^{})();

没有意义。唯一()可以去的地方是在^{}

void (^x)() = ^{}();

但是^{}()有类型void,没有类型void (^)()

总结一下:你不能同时声明一个块变量并调用它。您必须声明并初始化变量,然后调用它

void (^x)() = ^{};
x();

或声明它然后分配并调用它

void (^x)();
(x = ^{})();

或者只是分开所有三个:

void (^x)();
x = ^{};
x();

作为一个总结性的想法,假设同时声明和调用块是可取的。如果我们决定允许类似 的代码(void (^x)() = ^{})();,那么为了保持一致性,我们还必须允许类似++(void x = 4);or的代码(void x = 1) + (void y = 2);。我希望你会同意这些在 C 中看起来很奇怪。

于 2012-08-19T05:13:08.427 回答
3

作为一个类比,考虑:

这编译:

if (42) { }

这编译:

int x;
if (x = 42) { }

但这不会:

if (int x = 42) { }
于 2012-08-19T08:48:46.657 回答