Is it possible to simplify the setter of this bitmask wrapper? [duplicate] - objective-c

It's common to perform a check and set/clear a flag, eg:
if (some_test) {
flag |= SOME_FLAG;
}
else {
flag &= ~SOME_FLAG;
}
A convenient way around this I found so far is...
flag = (some_test) ? (flag | SOME_FLAG) : (flag & ~SOME_FLAG);
This could be made into a macro and its OK, but is there some bit-twiddeling magic to avoid referencing flag twice?
(in case multiple instantiations of flag causes overhead).
Example of what I'm looking for (if C could do ternary operations on operators), is...
flag ((some_test) ? (|=) : (&= ~) SOME_FLAG;
The example above is only to describe what I'm looking for, of course it wont work in its current form.

flag |= SOME_FLAG
is an expression, so you can use a macro
#define SET_FLAG(flag, some_test) \
((some_test) ? ((flag) |= SOME_FLAG) : ((flag) &= ~SOME_FLAG))
which evaluates flag only once, and when you use it, you need to type flag only once.
SET_FLAG(a->b->c->d, test);

I know you don't want to access flag twice. But you should be sure that is where the cost is. Often, the conditional jump is more expensive. On the last embedded processor I worked on, the fastest code would have looked like this:
flag &= ~(SOME_FLAG);
flag |= (some_test!=0) * SOME_FLAG;

If you want to define a macro and have it avoid evaluating the mask twice then you could do it like this:
#define SETT(FLAG, MASK_T, MASK, TEST) \
do {\
MASK_T mask = (MASK);\
FLAG &= ~mask;\
FLAG |= ((TEST) != 0) * mask;\
}\
while(false)
#define SET(FLAG, MASK, TEST) SETT(FLAG, unsigned, MASK, TEST)

Related

What does ^= mean in Objective-C?

I found this part of the code "^ =" in some old project, I saw how it changes state when I call "status ^ = YES;". Can someone explain to me what this is?
BOOL status = YES;
status ^= YES;
https://en.wikipedia.org/wiki/Bitwise_operations_in_C
The bitwise XOR (exclusive or) performs a logical XOR function, which is equivalent to adding two bits and discarding the carry. The result is zero only when we have two zeroes or two ones. XOR can be used to toggle the bits between 1 and 0. Thus i = i ^ 1 when used in a loop toggles its values between 1 and 0.
So status ^= YES is a wiseass way of toggling between 1 and 0, aka YES and NO. Mere mortals would say status = !status.

What does "macro" mean in Objective-C?

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.

Using logical || with enum values

I have an MPMoviePlayerController instance. I wish to check its playbackState property for one of a number of values. As such I do something like this:
if (moviePlayer.playbackState == (MPMoviePlaybackStateStopped ||
MPMoviePlaybackStatePlaying ||
MPMoviePlaybackStatePaused)) {
// ...
// Perform some logic
// ...
}
This works as expected but causes a compiler warning:
Use of logical '||' with constant operand.
The compiler's fix is to use the bitwise | operator instead. Searching on Stack Overflow you will find a couple of answers suggesting the same thing. BUT using the bitwise OR really isn't what I need here.
MPMoviePlaybackState is declared in MPMoviePlayerController.h:
enum {
MPMoviePlaybackStateStopped,
MPMoviePlaybackStatePlaying,
MPMoviePlaybackStatePaused,
MPMoviePlaybackStateInterrupted,
MPMoviePlaybackStateSeekingForward,
MPMoviePlaybackStateSeekingBackward
};
typedef NSInteger MPMoviePlaybackState;
This isn't a bitmask (and nor would it make much sense for it to be so — the enumerated values are mutually exclusive modes, not flags to be combined). I really do want to use the logical ||.
(In my particular case, with the underlying values being 0,1,2 the bitwise example might work but that's just a coincidence.)
How should I rephrase to avoid the warning or what #pragma clang diagnostic ignored ... can I use to silence the warning?
(Bonus points for pointing to a list of all such diagnostics — I cannot seem to locate one in the manual.)
Thanks in advance!
Obviously, the (enumval1 || enumval2 || ..) is wrong. You can't use the || operator like this, but only with logical expressions.
The | operator works, because it's a simple bitwise OR, which will do job for you only and only if your enum members are different powers of 2 (e.g. 1, 2, 4, 8, ...).
It's connected with bitwise representation of numbers in binary, which , if the number if the power of 2, is like this: 2->10, 4->100, 8->1000 etc. So, for 2 | 8 it will be like 0010 | 1000 = 1010, which isn't zero, and if statement will proceed.
The compiler warnings are fully right and helping at this point. Use the switch(..) or if(..) else if(..) statements, or make your enum like this:
enum yourEnum
{
enumval1 = 1 << 0;
enumval2 = 1 << 1;
enumval3 = 1 << 2;
// ...
}
why wouldn't you just do this?
if ((moviePlayer.playbackState == MPMoviePlaybackStateStopped) ||
(moviePlayer.playbackState == MPMoviePlaybackStatePlaying) ||
(moviePlayer.playbackState == MPMoviePlaybackStatePaused)) {
// ...
// Perform some logic
// ...
}
I suggest using a switch/case block with fall trough logic like that:
switch(moviePlayer.playbackState){
case MPMoviePlaybackStateStopped: /* falls through */
case MPMoviePlaybackStatePlaying: /* falls through */
case MPMoviePlaybackStatePaused: /* falls through */
// your stuff
}
This will result in the intended behaviour with as less code as possible. Enums are made for exact the switch case kind of business. And they are performance optimized more than "if" statements, becuase the CPU does not even have to test the values when reaching the code. The compiler calculates the correct ASM jump offset at that location. So its as fast as lighning :)

Specifying variable range in Verilog using for loop

I am trying to write this code:
for (i = 0; i <= CONST - 1'b1; i = i + 1'b1)
begin : loop_inst
if (i < 3)
begin
if (changed[i] & !done_q[i])
begin
writedata[3-i] = en[i];
writedata[2-i:0] = readdata[2-i:0];
writedata[15:4-i] = readdata[15:4-i];
end
end
else
...
Basically, the location of the bit I am trying to write to (en) changes depending on which address I am talking to, depending on i. This code is not synthesizable because i is not a constant.
Is there any other workaround to this? The only workaround I know is writing out those three statements CONST times. I am hoping I DON'T have to do that in the end. Is there any other solution?
It looks like you're trying to copy readdata to writedata all the time, but fill in the LSBs with en if certain special case conditions are met. I'm also going to assume that the for loop you have is in an always block, and that you're intending to build combo logic.
The for loop as you've it written doesn't make much sense to me from a hardware perspective. A for loop is used for building arrays of logic, and as you've
written it you'll have at least 3 logic cones trying to set values on the entire writedata bus. (If it generates anything at all, it'll be some weird priority structure).
That said, it's probably the range selects that your compiler is complaining about, ie the writedata[2-i:0] rather than the writedata[3-i] = en[i]; (anything with : in the part select). If you want to do something along those lines, you can use 'indexed part selects' ( +: or -:) but there are better solutions in this case.
I'd rewrite it as follows - assuming I've assumed correctly :)
always #( /*whatever*/ ) begin
// default assignment
writedata = readdata;
// overwrite some bits in writedata for special cases
for(i=0; i<3; i++) begin
if( changed[i] & !done_q[i] )
writedata[3-i] = en[i];
end
end
In this code, I'm setting writedata to readdata, and then tweaking the resulting value of writedata if the special cases are in play. The for loop is building 3 logic cones, one for each of the bits in writedata[3:1]. I'd double-check if the bit mapping is what you intend -ie, mapping en[2:0] on to writedata[1:3].

Simulater/Generated switch statement range in c

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.