I am new to iOS development and I just want to know the meaning of macro in Objective-C?
I have found that "macro" is used with #define but still do not get its meaning.
http://www.saturngod.net/ios-macro-define-value-with-condition
Yes, Larme is right. Macros can be used in many languages, it's not a specialty of objective-c language.
Macros are preprocessor definitions. What this means is that before your code is compiled, the preprocessor scans your code and, amongst other things, substitutes the definition of your macro wherever it sees the name of your macro. It doesn’t do anything more clever than that.
Almost literal code substitution. e.g.-
Suppose you want a method to return the maximum of two numbers. You write a macro to do this simple task:
#define MAX(x, y) x > y ? x : y
Simple, right? You then use the macro in your code like this:
int a = 1, b = 2;
int result = 3 + MAX(a, b);
EDIT:
The problem is that the preprocessor substitutes the macro definition into the code before compilation, so this is the code the compiler sees:
int a = 1, b = 2;
int result = 3 + a > b ? a : b;
C order of operations requires the sum 3 + a be calculated before the ternary operator is applied. You intended to save the value of 3 + 2 in result, but instead you add 3 + 1 first, and test if the sum is greater than 2, which it is. Thus result equals 2, rather than the 5 you expected.
So you fix the problem by adding some parentheses and try again:
#define MAX(x, y) ((x) > (y) ? (x) : (y))
A macro is a fragment of code which has been given a name. Whenever the name is used, it is replaced by the contents of the macro. There are two kinds of macros. They differ mostly in what they look like when they are used. Object-like macros resemble data objects when used, function-like macros resemble function calls.
An object-like macro is a simple identifier which will be replaced by a code fragment. It is called object-like because it looks like a data object in code that uses it. They are most commonly used to give symbolic names to numeric constants.
You create macros with the ‘#define’ directive. ‘#define’ is followed by the name of the macro and then the token sequence it should be an abbreviation for, which is variously referred to as the macro's body, expansion or replacement list. For example,
#define BUFFER_SIZE 1024
defines a macro named BUFFER_SIZE as an abbreviation for the token 1024. If somewhere after this ‘#define’ directive there comes a Objective C statement of the form
foo = (char *) malloc (BUFFER_SIZE);
The Objective C compiler will see the same tokens as it would if you had written
foo = (char *) malloc (1024);
You can also define macros whose use looks like a function call. These are called function-like macros. To define a function-like macro, you use the same ‘#define’ directive, but you put a pair of parentheses immediately after the macro name.
Like:
#define isIphone([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
#define GetImage(imageName) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:#"png"]]
Macros are compile time constants. That means they will replaced with actual values in the compile time.
#define MIN_VALUE 3 // Definition
if(x > MIN_VALUE) // Usage
{
}
While compiling it actually looks like
if(x > 3) // During compilation
{
}
Wikipedia has the answer, under Macro.
Definition:
The term originated with macro-assemblers, where the idea is to make available to the programmer a sequence of computing instructions as a single program statement, making the programming task less tedious and less error-prone.
Usage:
Keyboard and mouse macros that are created using an application's built-in macro features are sometimes called application macros. They are created by carrying out the sequence once and letting the application record the actions. An underlying macro programming language, most commonly a Scripting language, with direct access to the features of the application may also exist.
Related
Let's review Clang's MIN macro through this article: Deep learning IOS development of macro. The final result is what you can also find here:
#define __NSX_PASTE__(A,B) A##B
#define __NSMIN_IMPL__(A,B,L) ({\
__typeof__(A) __NSX_PASTE__(__a,L) = (A);\
__typeof__(B) __NSX_PASTE__(__b,L) = (B);\
(__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L);\
})
But I don't understand the need of defining __NSX_PASTE__. Wouldn't it be the same and more readable to use directly:
#define __NSMIN_IMPL__(A,B,L) ({\
__typeof__(A) __a##L = (A);\
__typeof__(B) __b##L = (B);\
(__a##L < __b##L) ? __a##L : __b##L;\
})
The simple answer is the __NSX_PASTE__ is required as without it the __COUNTER__ macro (not shown in the question but see the full source in the linked article, or look at the definition in Apple's NSObjCRuntime.h) will not be expanded. This is due to the weird and wonderful way the C Preprocessor works and how it handles stringification and concatenation, a good place to read how all this works is the GCC documentation on macros.
To see the results with and without the __NSX_PASTE__ put your above macros in a test file, say test.m, in Xcode renaming __NSMIN_IMPL__ to MY__NSMIN_IMPL__ (or you'll get a duplicate macro warning), add the macro you omitted - again renamed to avoid clashes:
#define MY_MIN(A,B) MY__NSMIN_IMPL__(A,B,__COUNTER__)
and add some code which uses MY_MIN. Now in Xcode select the menu item Product > Perform Action -> Preprocess "test.m" - this will show you the result after the preprocessor has run. If you try it with your version of __NSMIN_IMPL__ which does not use __NSX_PASTE__ you will see __COUNTER__ is not expanded.
HTH
Is there a way in VBA to create classes and/or methods that have a limited list of acceptable constants to use as arguments or in assignment statements?
These exist already in VBA per the images below:
I would like to incorporate this in my classes.
It's not a limited set of constants. You type xlsheethidden the program sees 0. The compiler puts 0 into the program. Nothing stops you doing this. ReportCS1.Visible = 1,000,000. It's an aid to writing programs, it doesn't form part of the finished program.
If you want to limit what can be passed then you'll need to write code checking what was passed, if wrong do err.raise(&h80070000 OR 13, blah,blah, blah).
This turns a WinError into a HResult - 13 seems resonable. = 0x8007000d
//
// MessageId: ERROR_INVALID_DATA
//
// MessageText:
//
// The data is invalid.
//
#define ERROR_INVALID_DATA 13L
Tim Williams answered my question in his comment. Thanks Tim!
You can create an Enum See: cpearson.com/excel/Enums.aspx
The idea is to setup several fixed CGPoint values with macros, and read them in code flexibly (randomly or with provided integer value)
I have a header file defining several CGPoints value like this:
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
I'm generating a random integer in my code between 1 to 3, and plan to read the CGPoint value in the macro according to the integer value. But don't know how to do it. After learning other tutorials about preprocessors, I write my code like following.
#define kSpawnPoint1 {550,20}
#define kSpawnPoint2 {550,80}
#define kSpawnPoint3 {200,175}
#define kSpawnPoint(x) kSpawnPoint##x
in the m file:
int tempInt = 1;
CGPoint tempSpawnPoint = kSpawnPoint(temInt);
However it doesn't work.(with warning: undeclared identifier 'kSpawnPointspawnPoint') How can I make this right? And is it the right way to pre-define several CGPoint? I think I must use the preprocessor to achieve this considering future multi-screen resolution support would be easier to implement in macro too, and my kSpawnPoints would not be the same with different screen resolution.
Macros only operate on text, not the values of variables. When you write kSpawnPoint(an_int), the preprocessor takes the literal string "an_int" and then pastes it, so you end up with kSpawnPointan_int. Thus, you would have to put a literal number as the argument in order to end up with one of your points: kSpawnPoint(1) -> kSpawnPoint1 -> {550, 20}
To choose randomly among your macros, you will have to put them into a structure that will exist at runtime, like an array or a switch statement.
I have a simple c program for printing n Fibonacci numbers and I would like to compile it to ELF object file. Instead of setting the number of fibonacci numbers (n) directly in my c code, I would like to set them in the registers since I am simulating it for an ARM processor.How can I do that?
Here is the code snippet
#include <stdio.h>
#include <stdlib.h>
#define ITERATIONS 3
static float fib(float i) {
return (i>1) ? fib(i-1) + fib(i-2) : i;
}
int main(int argc, char **argv) {
float i;
printf("starting...\n");
for(i=0; i<ITERATIONS; i++) {
printf("fib(%f) = %f\n", i, fib(i));
}
printf("finishing...\n");
return 0;
}
I would like to set the ITERATIONS counter in my Registers rather than in the code.
Thanks in advance
The register keyword can be used to suggest to the compiler that it uses a registers for the iterator and the number of iterations:
register float i;
register int numIterations = ITERATIONS;
but that will not help much. First of all, the compiler may or may not use your suggestion. Next, values will still need to be placed on the stack for the call to fib(), and, finally, depending on what functions you call within your loop, code in the procedure are calling could save your register contents in the stack frame at procedure entry, and restore them as part of the code implementing the procedure return.
If you really need to make every instruction count, then you will need to write machine code (using an assembly language). That way, you have direct control over your register usage. Assembly language programming is not for the faint of heart. Assembly language development is several times slower than using higher level languages, your risk of inserting bugs is greater, and they are much more difficult to track down. High level languages were developed for a reason, and the C language was developed to help write Unix. The minicomputers that ran the first Unix systems were extremely slow, but the reason C was used instead of assembly was that even then, it was more important to have code that took less time to code, had fewer bugs, and was easier to debug than assembler.
If you want to try this, here are the answers to a previous question on stackoverflow about resources for ARM programming that might be helpful.
One tactic you might take is to isolate your performance-critical code into a procedure, write the procedure in C, the capture the generated assembly language representation. Then rewrite the assembler to be more efficient. Test thoroughly, and get at least one other set of eyeballs to look the resulting code over.
Good Luck!
Make ITERATIONS a variable rather than a literal constant, then you can set its value directly in your debugger/simulator's watch or locals window just before the loop executes.
Alternatively as it appears you have stdio support, why not just accept the value via console input?
Is there a hack to support range case in a c(99?) or objective C switch statement ?
I know this is not supported to write something like this:
switch(x)
case 1:
case 2..10:
case 11:
But I was thinking there should be a way to generate code with a #define macro. Of course
I can define a macro with the list of cases but I was hoping for a more elegant way like
CASERANGE(x,x+10) which would generate:
case x
case x+1
case x+2
is it even possible ?
GCC has an extension to the C language that allows something similar to your first example, but other than that, if there was a portable/ANSI way of doing it, it would have been done by now. I don't believe there is one.
Doing this with macros is near to or impossible. Compiler extensions exist, but they are compiler specific and not cross-platform/standard. There is no standard way to do this, use if/else chains instead.
In modern C (C99, with variable length macros), doing this with macros is possible. But you probably wouldn't want to code this completely yourself. P99 provides a toolbox for this. In particular there is a meta-macro P99_FOR that allows you to do unrolling of finite length argument lists.
#define P00_CASE_FL(NAME, X, I) case I: NAME(X); break
#define CASES_FL(NAME, ...) P99_FOR(NAME, P99_NARG(__VA_ARGS__), P00_SEQ, P00_CASE_FL, __VA_ARGS__)
would expand CASES_FL(myFunc, oi, ui, ei) to something like
case 0: myFunc(oi); break; case 1: myFunc(ui); break; case 2: myFunc(ei); break
Edit: to reply to the concrete question
#define P00_CASESEP(NAME, I, X, Y) X:; Y
#define P00_CASERANGE(NAME, X, I) case ((NAME)+I)
#define P99_CASERANGE(START, LEN) P99_FOR(START, LEN, P00_CASESEP, P00_CASERANGE, P99_REP(LEN,))
where P00_CASESEP just ensures that there are the :; between the cases, and P99_REP generates a list with LEN empty arguments.
You'd use that e.g as
switch(i) {
P99_CASERANGE('0',10): return i;
}
Observe the : after the macro to keep it as close as possible to the usual case syntax, and also that the LEN parameter has to expand to a plain decimal number, not an expression or so.