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

How*_*ard 6 iphone xcode objective-c llvm ios

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

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

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

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

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

@implementation AppDelegate

- (void) applicationDidFinishLaunching:(UIApplication *)application
{
    NSSetUncaughtExceptionHandler(&exceptionHandler);
...
Run Code Online (Sandbox Code Playgroud)

jus*_*tin 16

从GCC手册:

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

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

Clang为GCC兼容性借用了这个选项,因为它很有用(我认为这是Clang开发者的这个).

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

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

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

1)我写了一个错字:

// file.h
extern void MONExceptionHandler(NSException * exception);
Run Code Online (Sandbox Code Playgroud)

// file.m
void MONExceptionhandler(NSException * exception) {
  …
Run Code Online (Sandbox Code Playgroud)

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

// file.m
static void MONExceptionHandler(NSException * exception) {
  …
Run Code Online (Sandbox Code Playgroud)

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

// file.h
extern void MONExceptionHandler(NSException * exception);
Run Code Online (Sandbox Code Playgroud)

警告:

// file.m
void MONExceptionHandler(NSException * exception) {
  …
Run Code Online (Sandbox Code Playgroud)

没有警告:

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

void MONExceptionHandler(NSException * exception) {
  …
Run Code Online (Sandbox Code Playgroud)

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


BJ *_*mer 7

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

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