"This function declaration is not a prototype" warning in Xcode 9

47,131

The block declaration with empty parenthesis:

void (^)()

has the same semantics as a function pointer with empty parenthesis:

void (*)()

It does not mean that there are no arguments. It means the arguments are not specified, therefore it opens the way to bugs since you can call it in the following ways:

void (^block)() = ...
block();
block(10);
block(@"myString");

When declaring blocks with no parameters, always use:

void (^)(void)

Apple was not doing that correctly everywhere and they are not probably fixing that for old APIs for compatibility reasons. You will have to keep that warning there until you move to the newer API.

You can also turn off that warning (-Wstrict-prototypes): enter image description here

or using #pragma (thanks @davidisdk):

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wstrict-prototypes"

- (void)application:(UIApplication *)application
handleActionWithIdentifier:(NSString *)identifier
forRemoteNotification:(NSDictionary *)userInfo
   withResponseInfo:(NSDictionary *)responseInfo
  completionHandler:(void (^)())completionHandler {

}
#pragma clang diagnostic pop

See the LLVM discussion here or the bug on openradar.

Note that's there was no change in the internal working of the APIs, all code will still work. We will only know that the API is not as good as it should be.

Share:
47,131
Hans Knöchel
Author by

Hans Knöchel

Updated on April 04, 2020

Comments

  • Hans Knöchel
    Hans Knöchel about 4 years

    When using Xcode 9, there are some compiler warnings saying This function declaration is not a prototype. It suggests to add void to the method body, which will resolve it. The issue I am having is that those warnings are also thrown for system-API's like UIApplication delegate-methods:

    - (void)application:(UIApplication *)application
        handleActionWithIdentifier:(NSString *)identifier
             forRemoteNotification:(NSDictionary *)userInfo
                  withResponseInfo:(NSDictionary *)responseInfo
                 completionHandler:(void (^)())completionHandler
    

    This could be resolved by the following:

    - (void)application:(UIApplication *)application
        handleActionWithIdentifier:(NSString *)identifier
             forRemoteNotification:(NSDictionary *)userInfo
                  withResponseInfo:(NSDictionary *)responseInfo
                 completionHandler:(void (^)(void))completionHandler
    

    Now I am wondering if the delegate methods will still work on the long-term or Apple will insert the void in later iOS 11 Beta versions. I am curious because if I include the void body, Xcode will complain about mismatching method-selectors (which makes sense). Did someone experience the same issue so far?

  • davidisdk
    davidisdk almost 7 years
    You can also use pragmas to remove the warning when implementing iOS API: #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wstrict-prototypes" - (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler { #pragma clang diagnostic pop
  • Edison
    Edison almost 7 years
    Got about 20 warning of these with the JBChartView API. It's nice to be able to turn them off until they decide to update for Swift 4.
  • Sulthan
    Sulthan almost 7 years
    @tymac This is an objc warning. It has nothing to do with Swift.
  • pkamb
    pkamb over 6 years
    > "When declaring blocks with no parameters, always use (void)" < Can you add what that should look like in code? As an alternative to void (^)() or void (*)()
  • Ben Stock
    Ben Stock over 6 years
    @pkamb When your block doesn't take any parameters (i.e. void(^)()), explicitly include void in the parentheses: void(^)(void).
  • Pryftan
    Pryftan almost 5 years
    You know I tend to forget to add (void) to functions that take no parameters (well: sometimes) and so saw this question/answer. As soon as I saw the first sentence here 'The block declaration with empty parenthesis' I remembered this and why it's a problem. And then I saw the next line and was totally baffled. This must be Objective C? If so it's a reminder of why I find it such a hideous language. The (^) totally threw me off. Either way I appreciate the answer - particularly the first line - as it brought me back to 'reality' (so to speak). Ta!
  • Sulthan
    Sulthan almost 5 years
    @Pryftan Objective-C is a pretty nice language actually, the syntax is easy to understand and consistent. Definitely not hideous. It's just a bit different then the languages with syntax similar to C++. It's just a different language development path.
  • Pryftan
    Pryftan almost 5 years
    @Sulthan I had a very bad reaction to C++! :) Sure it's different but I find it quite hideous. However this is just my preference and it hardly matters really, hey? It works for some people and that's all that matters really. I am biased for C (not much to it, aesthetically appealing to my eyes - though it's unfortunately been increasing in size and looking more ugly in recent years due to the standard body...) and admittedly I have fond memories of assembly. Cheers.