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

Iphone 奇怪的LLVM警告:没有以前的函数原型,iphone,objective-c,ios,xcode,llvm,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)

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

以前没有exceptionHandler函数的原型

但是为什么我下面的代码中需要它们呢

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

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

@implementation AppDelegate

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

如果您声明的函数仅用于此文件,请在声明前加上
static
关键字,警告将消失。实际上,您正在声明一个全局函数;理论上,它可以在你的应用程序中的任何地方调用。但由于你没有给它原型,没有其他人可以称之为

因此,据我所知,该警告试图让您澄清静态函数和全局函数之间的意图,并阻止您在仅声明静态函数时声明全局函数。

来自GCC手册:

-Wmissing原型(仅限C和Objective-C)

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

Clang借用这个选项是为了与GCC兼容,因为它很有用(我认为这是Clang开发人员的选择)

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

简而言之,您已经要求编译器通过启用此选项来告诉您何时非限定定义与声明不匹配。您应该将其限定为
extern
,并使其对其他人可用(例如,将其放在标题中),或者将其声明为
static
。如果使用C++ <代码>内联也是一种选择。 当然,隐式可见性是众所周知的,但我通常认为该选项在以下场景中很有用:

1) 我打字打错了: 及

2) 我应该明确说明符号的可见性: 3) 我忘了
#包括声明函数的头文件
: 警告:

// file.m
void MONExceptionHandler(NSException * exception) {
  …
没有警告:

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

void MONExceptionHandler(NSException * exception) {
  …

所以这里有基本原理、历史和一些例子——同样,
——Wmissing prototype
是一个选项。如果您相信自己可以使用它,那么就这样做。我的偏好是明确的,让程序检测潜在的和实际的问题,这样我就不用手动了。

< P>我认为这对C++代码非常有用。例如,我有一个标题

class MyClass {
public:
    void hello();
};
和.cpp文件

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

因此,此警告确保您正在实现已知的函数(不要错过键入的名称或不同的参数格式)。

此警告提醒您不能从上面编写的另一个方法调用您的方法。在C语言中,声明/实现的顺序非常重要,并给出了您可以访问或不能访问的内容之间的区别。

您是否关心方法的声明?是否将
exceptionHandler
定义在与
ApplicationIDFinishLaunching:
方法相同的文件中?而且,在使用之前是否对其进行了定义@一二三 是的,所有代码都在AppDelegate中定义。m@DavidSchwartz没有错误,只是LLVM警告显示如果我错过了函数原型是的,我正在使用作为全局函数。但正如您所看到的,如果我在**相同的文件中定义了原型**,那么警告就会消失,因此我认为可见性仍然是相同的?是的,可见性是相同的,但是编译器现在看到了一个原型,并且假设任何人都可以在原型中包含该文件,如果他们想进行调用的话。仅允许.h文件中的原型消除警告可能会更好,但这会更快地检测(从编译器的角度来看),并且同样有用(在我看来)。他调用的方法位于上面。你的回答在技术上是正确的,但对这个问题毫无用处。另外,在你之前还发布了另外两个正确答案。我认为我不应该因为给出了稍微不同的解释而得到-1,但社区决定;)
// file.m
void MONExceptionHandler(NSException * exception) {
  …
// file.m
#include "file.h"

void MONExceptionHandler(NSException * exception) {
  …
class MyClass {
public:
    void hello();
};
void hello() {
    cout << "hello";
}
void MyClass::hello() {
    cout << "hello";
}