奇怪的LLVM警告:没有以前的函数原型

时间:2012-01-14 06:03:07

标签: iphone objective-c ios xcode llvm

如果我错过了原型,XCode(LLVM)会提示我输入错误

以前没有用于exceptionHandler的函数的原型

但是为什么我的代码需要它们呢?

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

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

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(UIApplication *)application
{
    NSSetUncaughtExceptionHandler(&exceptionHandler);
...

4 个答案:

答案 0 :(得分:16)

从GCC手册:

  

-Wmissing-prototypes(仅限C和Objective-C)

     

如果在没有先前原型声明的情况下定义了全局函数,则发出警告。即使定义本身提供原型,也会发出此警告。目的是检测未在头文件中声明的全局函数。

Clang为GCC兼容性借用了这个选项,并且因为它很有用(我认为这是Clang开发人员)。

该选项存在,因此您可以防止自己犯一个容易避免的常见错误。为了清晰/意图,明确关于可见性/链接是很好的。

简而言之,您已经要求编译器通过启用此选项告诉您何时非限定定义与声明不匹配。您应该将其限定为extern并使其可供其他人使用(例如将其放入标题中),或将其声明为static。如果使用C ++ inline也是一种选择。

当然,隐式可见性是众所周知的,但我通常认为该选项在这些场景中很有用:

1)我写了一个拼写错误:

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

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

2)我应该明确这个符号的可见性:

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

3)我忘了#include声明函数的标题:

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

警告:

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

没有警告:

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

void MONExceptionHandler(NSException * exception) {
  …

所以有理由,历史和一些例子 - 再次,-Wmissing-prototypes选项。如果您相信自己禁用它,那么就这样做。我的偏好是明确的,让程序检测潜在的和实际的问题,所以我不必手动完成。

答案 1 :(得分:7)

如果您要声明仅在此文件中使用的函数,请在声明前加上static关键字,警告将消失。事实上,你宣布了一个全球性的功能;理论上它可以从你的应用程序中的任何地方调用。但是,由于你没有给它原型,其他任何人都无法调用它。

因此,正如我所理解的那样,警告试图让你澄清静态函数和全局函数之间的意图,并且当你只想声明一个静态函数时,不要声明你声明一个全局函数。

答案 2 :(得分:0)

我认为这对C ++代码最有用。例如,我有标题

class MyClass {
public:
    void hello();
};

和.cpp文件

void hello() {
    cout << "hello";
}

您将看到警告,因为函数void hello()没有原型。如果正确的实施应该是

void MyClass::hello() {
    cout << "hello";
}

因此,此警告确保您正在实现您所知道的功能(不要错过输入名称或不同的参数格式)。

答案 3 :(得分:0)

该警告警告您无法从上面编写的其他方法调用您的方法。在C语言中,声明/实现的顺序很多,并且给出了您可以访问或不能访问的内容之间的区别。