views:

709

answers:

5

I want to define a min and max methods in a Utils class.

@interface Utils

int min(int a, int b);
int max(int a, int b);

@end

But I don't want to have named parameters. It would be a too heavy notation. I wanted to use the C-style definition. But then [Utils min(a, b)] as a call doesn't work. What is my problem?

Thanks in advance for any help

A: 

Objective-C class methods use named parameters, period. That's just the way it is.

Why not make it a global, free function? You shouldn't need a Utils class for this kind of thing.

If you don't want to clutter the global namespace, you could use Objective-C++ (rename all .m files to .mm) and put it in a namespace.

Daniel Yankowsky
I didn't know i could do that. Global function seems the way to go. Thanks
Fred Polack
+9  A: 

It is already defined as a macro.

MIN(a, b)

MAX(a, b)

You dont need to redefine these ones.

Mongus Pong
Was about to point this out. Why write your own when it is already implemented in the obj-c runtime.
Brandon Bodnár
is it in the obj-c runtime or in the MacOS one. I'm using gcc-objective-c and I couldn't use these macros.
Fred Polack
It is defined in NSObjCRuntime.h, which many not be in the gcc-objective-c include files.
Brandon Bodnár
+1  A: 

Since you aren't using the OS X Implementation of objective-c, you may not have access to the predefined MIN and MAX macros.

You can define these yourself as

#define MIN(a,b)    ((a) < (b) ? (a) : (b))
#define MAX(a,b)    ((a) > (b) ? (a) : (b))

There is probably a better way to define them, but these will create the simple macros for your use. You can add them into any common .h file that your classes normally share.

Brandon Bodnár
+5  A: 

This is probably not a good idea for this particular application, but it is possible to write Objective-C methods with parameters “without names”, or rather with zero-length names:

+ min:(int)a :(int)b;
...
[Utils min:a :b]
Kevin Reid
I did not know you could do that. Upvote for something new I learned. Granted it just looks wrong to me to have no name between parts of the selector, but glad to know that it is possible.
Brandon Bodnár
wow. obj-c gets uglier with every passing lesson.
Yar
+2  A: 

There's a serious security issue with the solution posted by Brandon Bodnár (which by the time of this writing is marked as a valid solution).

Issue described here: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Min-and-Max.html And the (valid & secure) solution to it: http://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Typeof.html

Check it out yourself:

#include <stdio.h>

#define NAIVE_MAX(a,b) (a > b ? a : b)

#define NAIVE_MIN(a,b) (a < b ? a : b)

#if !defined MAX
#define MAX(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a > __b ? __a : __b; })
#endif

#if !defined MIN
#define MIN(a,b) \
({ __typeof__ (a) __a = (a); \
__typeof__ (b) __b = (b); \
__a < __b ? __a : __b; })
#endif

int main (int argc, const char * argv[]) {
    int a = 3;
    int b = 5;

#pragma mark NON-FATAL CASES:
    printf("NAIVE_MAX(%d, %d) => %d\n", a, b, NAIVE_MAX(a, b));
    printf("NAIVE_MIN(%d, %d) => %d\n", a, b, NAIVE_MIN(a, b));

    printf("MAX(%d, %d) => %d\n", a, b, MAX(a, b));
    printf("MIN(%d, %d) => %d\n", a, b, MIN(a, b));

    printf("\nEverything fine so far...\n\n");

#pragma mark FATAL CASES:
    //cache:
    int _a = a;
    int _b = b;
    printf("NAIVE_MAX(%d++, %d++) => %d\n", _a, _b, NAIVE_MAX(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MIN(%d++, %d++) => %d\n", _a, _b, NAIVE_MIN(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MAX(++%d, ++%d) => %d\n", _a, _b, NAIVE_MAX(++a, ++b));

    //reset:
    a = _a;
    b = _b;
    printf("NAIVE_MIN(++%d, ++%d) => %d\n", _a, _b, NAIVE_MIN(++a, ++b));

    printf("\nSee how the sh*t just hit the fan?\n\n");

#pragma mark NON-FATAL CASES:
    //reset:
    a = _a;
    b = _b;
    printf("MAX(%d++, %d++) => %d\n", _a, _b, MAX(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("MIN(%d++, %d++) => %d\n", _a, _b, MIN(a++, b++));

    //reset:
    a = _a;
    b = _b;
    printf("MAX(++%d, ++%d) => %d\n", _a, _b, MAX(++a, ++b));

    //reset:
    a = _a;
    b = _b;
    printf("MIN(++%d, ++%d) => %d\n", _a, _b, MIN(++a, ++b));

    printf("\nAh, much better now.\n\n");

    return 0;
}

So never ever use the naive implementation as seen in the code above (and as suggested by Brandon Bodnár, sorry buddy ;) ) if you want to avoid wort cases like these.

Regexident
+1 shit hits the fan! =)
PEZ