Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange LLVM warning: no previous prototype for function for

If I missed the prototype, XCode (LLVM) prompt me for error

no previous prototype for function for exceptionHandler

But why they are needed in my code below?

void exceptionHandler(NSException * exception); // Why this Line is needed?

void exceptionHandler(NSException * exception)
{
    // ....
}

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(UIApplication *)application
{
    NSSetUncaughtExceptionHandler(&exceptionHandler);
...
like image 557
Howard Avatar asked Jan 14 '12 06:01

Howard


2 Answers

From the GCC manual:

-Wmissing-prototypes (C and Objective-C only)

Warn if a global function is defined without a previous prototype declaration. This warning is issued even if the definition itself provides a prototype. The aim is to detect global functions that fail to be declared in header files.

Clang borrowed this option for GCC compatibility, and because it's useful (I would presume this of the Clang devs).

The option exists so you can prevent yourself from making a common mistake which may be easily avoided. It's nice to be explicit about visibility/linkage for clarity/intent's sake.

In short, you've asked the compiler to tell you when an unqualified definition does not match a declaration by enabling this option. You should either qualify that as extern and make it usable to others (e.g. put it in a header), or declare it static. If using C++ inline is also an option.

Of course, implicit visibility is well known, but I typically find the option useful in these scenarios:

1) I made a typo:

// file.h
extern void MONExceptionHandler(NSException * exception);

and

// file.m
void MONExceptionhandler(NSException * exception) {
  …

2) I should be explicit about the symbol's visibility:

// file.m
static void MONExceptionHandler(NSException * exception) {
  …

3) I forgot to #include the header which declared the function:

// file.h
extern void MONExceptionHandler(NSException * exception);

Warning:

// file.m
void MONExceptionHandler(NSException * exception) {
  …

No Warning:

// file.m
#include "file.h"

void MONExceptionHandler(NSException * exception) {
  …

So there's the rationale, history, and some examples - again, -Wmissing-prototypes is an option. If you trust yourself to work with it disabled, then do so. My preference is to be explicit, and to let programs detect potential and actual issues so I don't have to do it manually.

like image 76
justin Avatar answered Oct 05 '22 22:10

justin


If you're declaring a function only for use within this file, prefix the declaration with the static keyword and the warning will go away. As it is, you're declaring a global function; theoretically it could be called from anywhere within your app. But as you've given it no prototype, nobody else could call it.

So the warning, as I understand it, is trying to make you clarify your intentions between static functions and global functions, and discourage you from declaring a global function when you meant to declare only a static one.

like image 43
BJ Homer Avatar answered Oct 05 '22 23:10

BJ Homer