gmustudent
gmustudent

Reputation: 2209

Why does the compiler complain about my simple function call?

Just learning Objective-C coming from a Java background. I am trying to write a program that has no purpose other then to teach me how to write functions in this language and I am getting errors everywhere. The problem is since I just started with this language yesterday the errors make no sense to me. Here is what I have so far.

Main Method:

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

        prompt = writePromptMessage(prompt);

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

    return 0;
}

Special Method:

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

My Errors:

Upvotes: 2

Views: 1163

Answers (3)

zoul
zoul

Reputation: 104065

You either need to add a function declaration before main, or define the whole function there. As an example, this compiles:

#import <Foundation/Foundation.h>

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

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

And so does this:

#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);
}

The compiler automatically notices Objective-C methods (that’s a different thing), so that there’s no need to declare those in advance; this compiles fine:

@interface Foo : NSObject
@end

@implementation Foo

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

- (void) doB
{}

@end

Apparently the compiler is not this smart about regular C functions, probably to keep in line with the C language spec.

Upvotes: 2

mipadi
mipadi

Reputation: 410902

All these errors most likely stem from the same issue. It appears that you have not declared or defined writePromptMessage before your main method. In C (and Objective-C), you have to declare or define functions before you use them. The compiler doesn't know anything about writePromptMessage, resulting in your error messages.

Implicit declaration of function writePromptMessage is invalid in C99

means that you haven't declared writePromptMessage, so...

Implicit conversion of 'int' to 'NSString *' is disallowed with ARC

In C, functions are assumed to return an int by default; since you have not yet declared writePromptMessage, the compiler assumes it is a function that returns an int, which shouldn't be converted into a NSString *.

Incomplete integer to pointer conversion assigning NSString strong from int

See above (it's basically the same issue).

Conflicting Types for writePromptMessage

Oh! Now the compiler has seen writePromptMessage...but wait. It already assumed writePromptMessage returned an int, and now it sees that it returns NSString, resulting in an error.


If you put the definition of writePromptMessage before main, or at least declare its prototype, à la:

NSString *writePromptMessage(NSString * prompt);

before main, you should be okay.

Upvotes: 1

Adam Rosenfield
Adam Rosenfield

Reputation: 400454

Unlike Java, you need to add a function declaration (aka a function prototype) before the point where it's used. A function declaration is just like the function definition, but without the body (i.e. the code) of the function, and ending with a semicolon:

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

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

In order to be able to call a function, you need to have written a declaration before the usage site:

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

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

// definition follows

Alternatively, you can place the whole definition before the usage site, but this won't always be possible (e.g. if you have two functions which can call each other).

C and Objective-C do actually allow you to call functions that don't have visible declarations, but this is considered a deprecated feature because it's easy to misuse and cause subtle errors:

If a function is called without a visible declaration, the compiler creates an implicit declaration:

  • The implicit declaration takes an arbitrary number and types of parameters
  • The implicit declaration returns int

So, what happened is that the compiler is assuming that writePromptMessage returns int when it first sees it, which is wrong, and that causes a cascade of other errors. For functions which don't return int, you must never use implicit function declarations, and for functions which do return int, you should never use implicit function declarations.

Upvotes: 4

Related Questions