为什么编译器会抱怨我的简单函数调用?

时间:2012-11-14 16:39:13

标签: objective-c

刚刚学习来自Java背景的Objective-C。我正在尝试编写一个没有任何目的的程序,然后教我如何用这种语言编写函数,我到处都是错误。问题是因为我昨天刚开始使用这种语言,这些错误对我来说毫无意义。这是我到目前为止所拥有的。

主要方法:

int main (int argc, const char * argv[])
{
    @autoreleasepool
    {
        NSString * prompt = @"Hello World";

        prompt = writePromptMessage(prompt);

        NSLog(@"%@", prompt);
    }

    return 0;
}

特殊方法:

NSString *writePromptMessage(NSString * prompt)
{
    return prompt;
}

我的错误:

  • 函数writePromptMessage的隐式声明在C99中无效
  • ARC
  • 不允许将'int'隐式转换为'NSString *'
  • 指针转换的不完整整数从int
  • 指定NSString strong
  • writePromptMessage的冲突类型

3 个答案:

答案 0 :(得分:4)

与Java不同,您需要在使用它之前添加函数声明(也称为函数原型)。函数声明就像函数定义一样,但没有函数体(即代码),以分号结尾:

// This is a function declaration:
NSString *writePromptMessage(NSString * prompt);

// This is a function definition:
NSString *writePromptMessage(NSString * prompt)
{
    // Function body goes here
}

为了能够调用函数,您需要在使用站点之前编写声明

NSString *writePromptMessage(NSString * prompt);  // declaration

int main (int argc, const char * argv[])
{
    ...
    writePromptMessage(...);  // usage
}

// definition follows

或者,您可以将整个定义放在使用站点之前,但这并不总是可行的(例如,如果您有两个可以相互调用的函数)。

C和Objective-C实际上允许您调用没有可见声明的函数,但这被认为是一个不推荐使用的功能,因为它很容易被滥用并导致细微的错误:

如果在没有可见声明的情况下调用函数,则编译器会创建隐式 声明

  • 隐式声明采用任意数量和类型的参数
  • 隐式声明返回int

所以,发生的事情是编译器假设writePromptMessage在第一次看到它时返回int,这是错误的,并且会导致一系列其他错误。对于不返回int的函数,必须从不使用隐式函数声明,对于返回int的函数,应该从不使用隐式函数声明。

答案 1 :(得分:2)

您需要在main之前添加一个函数声明,或者在那里定义整个函数。举个例子,这个编译:

#import <Foundation/Foundation.h>

void hello(NSString *text) {
    NSLog(@"%@", text);
}

int main(int argc, const char * argv[])
{
   @autoreleasepool {
        hello(@"Foo");
    }
    return 0;
}

这样做:

#import <Foundation/Foundation.h>

void hello(NSString*);

int main(int argc, const char * argv[])
{
   @autoreleasepool {
        hello(@"Foo");
    }
    return 0;
}

void hello(NSString *text) {
    NSLog(@"%@", text);
}

编译器会自动注意到Objective-C 方法that’s a different thing),因此无需事先声明这些方法;编译好了:

@interface Foo : NSObject
@end

@implementation Foo

- (void) doA
{
    [self doB];
}

- (void) doB
{}

@end

显然,编译器对常规C函数并不聪明,可能与C语言规范保持一致。

答案 2 :(得分:1)

所有这些错误很可能源于同一问题。您似乎尚未在 writePromptMessage方法之前声明或定义main 。在C(和Objective-C)中,您必须在使用它们之前声明或定义函数。编译器对writePromptMessage一无所知,导致出现错误消息。

  

函数writePromptMessage的隐式声明在C99中无效

表示您尚未声明writePromptMessage,所以......

  

ARC

不允许将'int'隐式转换为'NSString *'

在C中,假定函数默认返回int;由于您还没有声明writePromptMessage,编译器会假定它是一个返回int的函数,不应该将其转换为NSString *

  

指针转换的不完整整数从int

指定NSString strong

见上文(基本上是同一个问题)。

  

writePromptMessage的冲突类型

哦!现在编译器已经看到了writePromptMessage ......但是等等。已假设writePromptMessage已返回int,现在它看到它返回NSString,从而导致错误。


如果您在 writePromptMessage之前添加main 的定义,或者至少声明其原型,则la:

NSString *writePromptMessage(NSString * prompt);
main之前

,你应该没事。