This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Operator overloading in C
If I have a struct:
typedef struct myStruct {
...
} myStruct;
myStruct myStructAdd(myStruct a, myStruct b);
I need something like this:
#define myStruct a + myStruct b myStructAdd(a, b)
// NOTE this code does NOT WORK. This is what the question is asking.
To make this syntax valid:
myStruct a;
myStruct b;
myStruct c = a + b;
Is there any way to use a #define to do this?
EDIT:
I'm not asking for alternatives to the + syntax. What I'm asking is if, and how, the preprocessor can be used to rewrite the plus syntax to standard C syntax on compile.
i.e. something like #define myStruct a + myStruct b myStructAdd(a, b) which turns myStructA + myStructB into myStructAdd(myStructA, myStructB) on compile.
Operator overloading simply isn't a feature of C or Objective-C. C++ allows you to define arbitrary behaviour for operators and custom types. In Objective-C, if two objects can be added together, then usually there is a method for that:
Foo *result = [foo1 fooByAddingFoo:foo2];
Or, if the class is mutable:
Foo *foo1 = [Foo fooWithBar:bar];
[foo1 addFoo:foo2];
If operator overloading is a must-have feature, use C++ instead, or use Objective-C++ (but keep in mind that C++ classes and Objective-C objects are totally and fundamentally different).
Edit:
The C proprocessor is conceptually very simple, and it knows very, very little about C's syntax, and nothing at all about C's types. If you wanted to overload an operator using the preprocessor, then it would have to learn every type (including custom types) used in your code, and it would have to perform static type checking in order to determine which function to invoke, and this is something that is way out of the scope of the preprocessor.
It's an interesting idea, but it's simply not possible.
There is no way for you to do that using the preprocessor. Also, as far as I known, there is no other feature that would provide this in objective C.
However, if you would use C++ (or objective-C++, which give you all features of both Objective C and C++) you could define an operator+, as follows:
struct myStruct
{
myStruct operator+(myStruct const & other)
{
return ...;
}
}
If you limit your question to the preprocessor then the answer is that it is impossible due to the fact that to define a macro that takes in arguments you have to have a parentheses macro like
#define __DO_STH(par1,par2)
Operator overloading the way you think of it does not use parentheses so you can not create any such macros
The only way to do that would be to make a simple parser which would be reading your code and whenever it encountered the structs you need being added with a plus sign spit out C code that replaces that with the function, but why do that and not use C++ where it's natively supported?
Also unless you are asking for purely academic purposes, it is my honest opinion that operator overloading always does more bad than good and is better avoided.
The only way I know is to use Objective-C++. To do this, give your implementation file the extension "mm" and you're good to go.
Related
I am familiar with C and am now learning Objective-C.
I often use function pointers
void (*callback)(int*restrict, char*restrict)
Will that be usable in Objective-C? Especially in structs, like so:
struct mytype myvar = {
.first = myCallback;
.second = myCallback2;
}
Also, I wish to have function prototypes like
void function(int * restrict a, char * restrict b);
char * function (char * a);
...
Are there no problems with using this style?
Clang (the default compiler used by Xcode) claims C11 support for Objective C (See Language Compatibility).
This means function pointers, restrict, structs, and declarations will all work as you would expect.
One word of advice: don't fight the system; it will create more work for yourself and less reliable software for your users. Programmers should be like water.
Empty your mind, be formless, shapeless — like water. Now you put water in a cup, it becomes the cup; You put water into a bottle it becomes the bottle; You put it in a teapot it becomes the teapot. Now water can flow or it can crash. Be water, my friend.
— Bruce Lee
Yes.
You can use any C strategy that you choose in your Objective-C app. You will still have to write some Objective-C in order to start your UIApplication (or use a third-party tool to do it for you).
One thing to keep in mind, though, is that int will be a different length depending on the machine and you should explicitly choose int32_t or int16_t or int8_t if you really don't want to use the NSInteger typedef that abstracts this machine difference.
Since we always use pointers to define variables, I was wondering if Objective-C is "pass by value", since like Java, the actual value would be passed by using its reference.
However, since it seems to be built up on top of C, would it have all the functionality of C?
C does not support pass-by-reference and Objective-C, being a strict superset of C doesn't either.
In C (and Objective-C) you can simulate pass-by-reference by passing a pointer, but it's important to remember that you're still technically passing a value, which happens to be a the value of a pointer.
So, in Objective-C (and C, for the matter) there is no concept of reference as intended in other languages (such as C++ or Java).
This can be confusing, so let me try to be clearer (I'll use plain C, but - again - it doesn't change in Objective-C)
void increment(int *x) {
*x++;
}
int i = 42;
increment(&i); // <--- this is NOT pass-by-reference.
// we're passing the value of a pointer to i
On the other hand in C++ we could do
void increment(int &x) {
x++;
}
int i = 41;
increment(i); // <--- this IS pass-by-reference
// doesn't compile in C (nor in Objective-C)
It is a strict superset of C.
It does the same as C.
It's one reason all Objects are actually pointers to structs.
Huge proponent of using the 'var' keyword in C# for cases where it's very clear. For instance, rather than this...
ThisIsMyReallyLongFooClassName foo = new ThisIsMyReallyLongFooClassName();
I can type this...
var foo = new ThisIsMyReallyLongFooClassName();
...and I still have a strongly-typed variable. The two are, for all intents and purposes, equal. The latter is just more readable (again, because it's clear. There are cases where it isn't and 'var' shouldn't be used. I don't want this to become a discussion of that however.)
I'm wondering if Objective-C has anything similar.
Yes and no.
You can use id foo = ... which will always work, but you lose the type information.
If you really want something equivalent, you could use auto foo = ... from C++11, but then you have to compile your file as Objective-C++, which has many other side effects.
Convention is to just spell out your types; it's annoying, but unlike C++, C#, Java where templates/generics can make typenames very long, it's usually manageable in Objective-C.
There is now, __auto_type. For example...
__auto_type test = #"Hello World";
...results in test having the type NSString*.
Here's a decent writeup:
https://medium.com/#maicki/type-inference-with-auto-type-55a38ef56372
The author suggests using
#define let __auto_type const
#define var __auto_type
in some shared header in your application to make the usage cleaner. I'm a bit wary of this kind of macro usage personally but I've been doing it for a while and the world is still turning... Maybe macro names less likely to cause a collision would be better.
No, there is no equivalent in Objective C. C++11 introduced the auto keyword to do it, but neither C nor Objective C has a similar capability.
The id is closest to C#'s dynamic keyword. It lets you achieve similar results to var, except that it does not let you access properties using the property syntax. It does let you invoke methods, including methods that implement property accessors.
You can do something like this:
__typeof([obj someMethod]) foo = [obj someMethod];
That's ugly, but if you have a snippet or macro defined to automatically generate it, then you don't have to type out the type names. For example:
#define LET(V, EXPR) __typeof(EXPR) V = (EXPR)
LET(vc, self.viewController); // equivalent to "UIViewController* vc = self.viewController;"
LET(d, [number doubleValue]); // equivalent to "double d = [number doubleValue];"
LET(foo, [[Foo alloc] init]); // equivalent to "Foo *foo = [[Foo alloc] init];"
Note: I'm not recommending this approach, as the convention in Objective-C is to write out the full type names or use id, and macros can be messy. But knowing about __typeof() can be handy.
There is the id keyword in Objective-C, but note that it is equivalent to the dynamic keyword in C# and not the var keyword. var is implicit typing - ie the type is inferred, but it is still static typing. dynamic and id are for dynamic typing and you lose type information.
I am afraid that no such equivalent exists in Objective C which would allow you to preserve strong typing.
You can use id keyword in objective C, but it doesn't work as c#
in c#
var stringVar = ...
stringVar worked as string variable and you can use access the string function by doing stringVar.function
id stringVar = [NSString ...]
but it still work as normal id type.
I've been learning Obj-C since getting a MBP about a month ago. I'm fairly comfortable with what I'm learning & things are slotting in to my rusty old brain pretty well. Except there's one thing I'm just not sure if I'm overlooking, or if just going over my head, or I'm looking for something that isn't there.
Most languages I've used have a way of slotting in an inline function call to simplify the coding, & I'm just not sure how this translates in Obj-C. Especially I'm referring to when the function being called is in a separate file, for the coding purposes of keeping similar functions together.
So far, the only way I've seen in Obj-C guides & tutorials is to create a class with methods & then instantiate that class (within the class you're working) to access the method in a [message]. Is this the way it's done in Obj-C? The only way? The best way for some reason? I know classes have their place in many languages & I use them myself, but I'm referring to simple little inline function calls where I usually wouldn't go to the trouble of creating a complete class.
To use a simple C++ console example of my point (only showing the .cpp files):
// example mainFile.cpp
#include <iostream>
#include "mainFile.h"
#include "functionsFile.h"
using namespace std;
void theMainFunction () {
int resultBeforeAltering = 100;
// alterTheResult() = simple inline function call I'm referring to
cout << "The result is " << alterTheResult(resultBeforeAltering);
}
.
// example functionsFile.cpp - could contain many similar functions
#include "functionsFile.h"
int alterTheResult (int resultToAlter) {
int alteredResult;
if (resultToAlter < 100) {
alteredResult = resultToAlter * 2;
} else {
alteredResult = resultToAlter * 3;
}
return (alteredResult);
}
Is there an equivalent approach to do alterTheResult() in Obj-C (assuming mainFunction() was an Obj-C method)?
I've seen reference to functions within Obj-C, but they seem to be C functions being referred to. C functions are not what I'm asking about here.
Thanks in advance, answers much appreciated.
Yes, the way to inline is to use C or C++ inlining -- that's perfectly legal (for C++, that will require compiling as ObjC++). An ObjC method will never be inlined (until LLVM produces a JIT compiler =p).
If you simply want to organize methods in another file, you may want to try an ObjC category:
// NSString_MONStuff.h
#interface NSString (MONStuff)
- (BOOL)mon_isPalindrome;
#end
// NSString_MONStuff.m
#implementation NSString (MONStuff)
- (BOOL)mon_isPalindrome { return ...; }
#end
Again, those will not be inlined.
You can also use C or C++ external functions or classes instead of categories for organization - the benefit is speed, size, reduced dependencies, and safety. The choice is yours, but there's no way to inline an objc method (it's a very dynamic langauge).
I've seen this operator pop up quite a few times in example code in "Learn Objective C on the Mac."
I believe it's an operator in the C language which Objective C inherits.
I tried Googling and searching Stack Overflow and oddly nothing came up.
Does it have an English name?
It has to do with structures.
When we have a struct available locally on the stack, we access its members with the . operator. For example:
CGPoint p = CGPointMake(42,42);
NSLog(#"%f", p.x);
However, if we instead have a pointer to a structure, we have to use the -> operator:
CGPoint *p = malloc(1*sizeof(CGPoint));
p->x = 42.0f;
NSLog(#"%f", p->x);
free(p);
-> is not specific to Objective-C. It's a C operator.
Now that's cleared, it's the member access operator, equivalent to a pointer dereference and then using the dot operator on the result.
Say you had a struct like this:
typedef struct Person {
char *name;
} Person;
Person *jacob = malloc(1*sizeof(Person));
So this statement:
jacob->name = "Jacob";
Is equivalent to this statement:
(*jacob).name = "Jacob";
Of course, don't forget the free:
free(jacob);
In C
a->b
is a shortcut for
(*a).b
which is for dereferencing of members of a struct that is pointed to.
This is useful, because of . binds stronger than the dereferencing operator * . So by using -> you avoid having to use these ugly parentheses.
It's a member selection (or access) equivalent to a pointer de-reference (as pointed out in comments)
a->member is equivalent to (*a).member in C/C++
The same thing that it means in C. It can be used to access the instance variables of objects directly, but generally this is not the best practice. The dot notation you're referring to is a property, not the usual C dot notation.
It's the "indirect member access operator". It's a C operator, which both Objective-C and C++ inherited.
This
a->b
is equivalent to:
(*a).b
but is less typing. (The parens are necessary in the expanded form due to precedence of * and ..)
a->b is equivalent to (*a).b, and designates member b of the object pointed to by a.
In the C standard, it is called the "structure/union pointer operator," which isn't really the catchiest name.
It's all been said, it is a shortcut for accessing members of a struct pointer, but just a note to add that you can access ivars using the same syntax due to the way the Objective-C runtime works:
#interface Foo : NSObject {
NSString *something;
}
/* ... SNIP ... */
NSLog(#"something = %#", foo->something); // Where foo is an instance of the Foo class
This is handy when you need to access ivars that aren't exposed by methods; specifically when you need to implement copyWithZone: on your objects.