Benji XVI
Benji XVI

Reputation: 2310

C function always returns zero to Objective C

I have an Objective C project incorporating a C file with some helper functions. However, functions in the C file that return a float are not working as expected.

C file:

float returnFloat() {
    return 10.0;
}

Meanwhile in an Objective C instance method:

float x;
x = returnFloat();

x is always 0.000000.

Edit

I have a bunch of "implicit declaration" warnings in the Objective C file, relating to use of the functions I have in the C file.

Assignments using functions that return int are working fine. Where an assignment is made from a function returning float, the debugger says "variable optimized away by compiler".

Is it likely I'm not correctly importing the C file within the Objective-C code? I have just let Xcode link it in automagically. Then, how come the problem only occurs for C functions that return float?

Upvotes: 2

Views: 1924

Answers (5)

Jorge Israel Peña
Jorge Israel Peña

Reputation: 38606

It's cause you want:

// the c way
float returnFloat() {
   return 10.0;
}

float result = returnFloat();

// the objective-c way
- (float) returnFloat {
   return 10.0;
}

float result = [self returnFloat]; // assuming this is an object

Not what you have. You're mixing C function prototypes with Objective-C. Try the C way mentioned above (Should be able to use it in Objective-C code).

Sorry if I misunderstood your question, I'm pretty sure my code is correct :)

EDIT: Clarification for all of the downvoters. In his first revision of the post he made it float returnFloat {} instead of float returnFloat() { }, which prompted my answer.

EDIT 2: Apparently that wasn't clear enough. In his first revision of his post, he was mixing the C way of writing function prototypes with the Objective-C way of writing function prototypes. You CAN use C functions in Objective-C, but you CAN'T mix the way of writing their function prototypes, as I explained above. Sorry for any confusion.

Upvotes: 0

Jed Smith
Jed Smith

Reputation: 15954

You have to use a .h file, just like with .m files, to declare what you're doing in another file. So, you need something like this for this scenario (these are incomplete):

returnfloat.c

float returnFloat() {
    return 10.0;
}

returnfloat.h

float returnFloat(void);

usefloat.m

#import "returnfloat.h"

- (void) someMethod {
    float ten = returnFloat();
}

The problem (given away by your "implicit declaration" warnings) is that the compiler is assuming that you are calling something that returns an int or id, not a float. When you work with C, things need to be prototyped (GCC will treat the .c file like C, and all C rules apply, even though you're in an Objective-C project).


If you'd like to see an example, here's something from one of my projects -- production code (you can write pure C in a file ending in .m, and GCC will treat it like Objective-C in some ways):

DebugF.m

#import "DebugF.h"

void __Debug(const char *file, int line, NSString *format, ...) {
#ifdef DEBUG
    /* Wraps NSLog() with printf() style semantics */
#endif
}

DebugF.h

#ifndef __DEBUGF_H_INCLUDED__
#define __DEBUGF_H_INCLUDED__

#ifdef DEBUG
#define DebugF(args...) __Debug(__FILE__, __LINE__, args)
#else
#define DebugF(...)
#endif /* DEBUG */

void __Debug(const char *file, int line, NSString *fmt, ...);

#endif /* __DEBUGF_H_INCLUDED */

SomeViewController.m

DebugF(@"Got these arguments: %u, %@, %@", 4, anObject, [anObject somethingElse]);

Upvotes: 13

Jonathan Leffler
Jonathan Leffler

Reputation: 754090

How did you declare 'returnFloat()' to your Objective-C program? Does it have a prototype in scope? If not, then your likely problem is that Objective-C is treating the function as returning an int, not a float, and havoc ensues (or you perceive that zero is returned).

Upvotes: 0

Nikolai Fetissov
Nikolai Fetissov

Reputation: 84189

I'm no Objective-C programmer, but in C world the compiler assumes int return type for any undeclared function that current module uses. It looks to me that creating a normal C header file containing:


#ifndef _MY_IMPORTANT_HEADER_
#define _MY_IMPORTANT_HEADER_
extern float returnFloat();
#endif

and including that into your .m file should make it all work:


#include "myheader.h"

Upvotes: 1

Matt Ball
Matt Ball

Reputation: 6618

How are you determining that x is 0.0000? A common mistake in debugging is to use the wrong format string in NSLog().

If you are, using NSLog(), make sure you're using the %f or some variant of it:

NSLog(@"x = %f", x);

(many people get mixed up and try to use %i instead)

EDIT: That's with the assumption that your C function prototype is correct and the lack of parentheses was just a typo here. If not, Blaenk's answer is likely correct.

Upvotes: -1

Related Questions