Passing block parameter that doesn't match signature

前端 未结 3 1414
南笙
南笙 2020-12-31 18:47

I\'m working with a block-based API and stumbled across a scenario where I was passing in a block parameter that had a signature that didn\'t match the typedef\'d parameter

相关标签:
3条回答
  • 2020-12-31 18:58

    Providing an empty arguments specification as in

    typedef void(^MyBlock)();
    

    means "unspecified" arguments. So the two types are compatible as written. Changing the first declaration to

    typedef void(^MyBlock)(void);
    

    specifies that the block takes no arguments and you'll get an error.

    K&R C specifies that an empty argument list means "unspecified". The C blocks spec says this is not true for block type declarations (cf. http://clang.llvm.org/docs/BlockLanguageSpec.html#block-variable-declarations) but: both GCC and Clang implement the K&R behavior as a language extension.

    0 讨论(0)
  • 2020-12-31 18:58

    From the Clang Blocks specification:

    Variadic ... arguments are supported. [variadic.c] A Block that takes no arguments must specify void in the argument list [voidarg.c]. An empty parameter list does not represent, as K&R provide, an unspecified argument list. Note: both gcc and clang support K&R style as a convenience.

    Basically, this is an ancient quirk of C syntax. In olden times, C function declaration syntax was rather different, and empty parentheses indicated that the function could be passed any number of arguments. For backwards compatibility, compilers have generally allowed the old-style function declaration syntax. And for some reason, Apple decided to simultaneously reject this syntax in the block standard while actually allowing it to be used with blocks in both GCC and Clang.

    So, long story short: To declare that a block takes no arguments, you need to explicitly type it as void(^MyBlock)(void)

    0 讨论(0)
  • 2020-12-31 19:04

    This is a C thing. A function or block prototype with an empty argument list means "the function (or block) takes any arguments you like". If you want to convey that the block should have no arguments, you need to explicitly say so like this:

    typedef void(^MyBlock)(void)
    

    This is largely historical from the days before ANSI when there weren't function prototypes and all function declarations (as opposed to definitions) looked like this:

    some_type function();
    
    0 讨论(0)
提交回复
热议问题