What constantly happens to me is this, when I'm using Xcode with Objective-C:
I'll be writing a switch/case statement. Typically, to make sure statements are separated, the programmer must make sure there are break;s between cases.
I often forget to put the break; statement in, so instead of the device executing only the the desired case, the device executes the case and then the case after it. This happens on both a physical device (iPhone 6) and on every simulated device on iOS Simulator.
Here's what the syntax of the failed statement looks like, with someInt being a number that is either 0 or 1:
switch (someInt)
{
case 0:
{
// some statements to execute if "someInt" is 0
}
case 1:
{
// some statements to execute if "someInt" is 1
break;
}
}
Note how, in case 0:, there is no break; statement. This causes case 0: to execute and then case 1 to execute, instead of just case 0 to execute.
Is there a way I can put a flag in Xcode so it warns me if I forget a break; statement?
I know many programmers have probably been confused for days, weeks on end, because of this problem.
I do not think that there is a compiler warning. This is, because "the programmer must make sure there are breaks between cases." is not fully correct. The programmer must make sure that there are breaks between the cases, if he wants the code not to fall through. (There are use cases for falling through.)
The background is that C was akin of replacement for assembler. In assembler you write a multi-selection with conditional jumps to the specific branch (case) and unconditionally jumps out of a branch (break), if you do not want to continue. (BTW: This is the reason for being case-branches no blocks, too.)
Of course, this is obsolete. You can simply use the automatic code generation of Xcode or replace switches with if-else if-else cascades.
This behaviour is an implicit part of the C language (which underlies Objective C) and although more often than not, you don't want the fall through to the next case, for better or worse, this is the way the language is defined.
Swift, on the other hand, doesn't require an explicit break as cases do not fall through.
Clang does define a warning -Wimplicit-fallthrough which generates a warning in the situation you describe, however it doesn't seem to be supported in the Clang included with Xcode 6.3.2. I don't have Xcode 7 installed yet to check if this is still true in that version.
Related
I'm really new to programming Objective-C and programming in general, so forgive me if this is a super obvious question:
I'm wondering if Objective-C runs code line by line. What I mean by that is if it processes one line before moving onto another, or if it just runs the next line regardless of whether the previous line is finished or not.
For example,
int difference = number1 - number2;
if (difference < 0) {
difference = difference + 10;
}
result = difference;
Say that number1 = 3 and number2 = 7. When I run this code, will it go line by line and run the if block before line 5 and give me result = 6, or will it start running the if block and line 5 at the same time and give me result = -4?
Thanks in advance!
EDIT: Changed modulo to addition because of Obj-C quirk.
As far as your thinking goes you may as well assume that it runs line by line.
In fact the compiler may put the code into a more efficient order (i.e. making sure that divisions aren't too close together, as this could make things slow). However even when the compiler does re-order things it makes sure that a result is calculated before it is needed. When you build the code in a fully optimised fashion (release mode) if you debug it you can see that the code has actually been re-ordered (the debugger jumps when you wouldn't expect it to). However as far as thinking about your code goes it's safe to assume that it runs it in the order you write it.
If you are new to programming, all programming languages you will meet at the beginning of your learning will execute statements sequentially. It means that the next one happens only after the previous one ends. However, languages like Objective C are not line-oriented and what matters are not lines but statements, like assignment ending with semicolon! or if statement.
I have written an if-clause that checks whether I should break the program for debugging or not:
if (a < 0) {
a = a;
}
a should not become negative, but I have found that it does, and I want to break for debugging to see why it becomes negative if that happens, hence I have written this if-clause. On the line a = a; I have set a breakpoint, which is supposed to stop the program if it enters the if-clause. The thing is that the line doesn't do anything (which is necessary in order not to mess anything up), so the line is optimized away and the breakpoint ends up after the if-clause. This trick usually works but apparently the compiler wasn't very found of it this time.
The language is C++, and I'm compiling with qmake (a Qt tool) and mingw.
My question is, how can I prevent the compiler from optimizing away lines of code when I have breakpoints set on them? Or is there some other way to conditionally break the program for debugging?
One possibility is to call an I/O function. In Java, one could write:
if (a < 0) {
System.out.printf("");
}
Similarly, in C/C++, one could write:
if (a < 0) {
printf("");
}
Even though the function call is effectively a no-op, the compiler doesn't know that, and is unlikely to optimize the call away.
Or is there some other way to conditionally break the program for debugging?
Many modern IDE allow one to set conditional breakpoints: Visual Studio, Eclipse.
I usually put a printf (or cout, or whatever is appropriate for the language that you are using) here so that I can set a breakpoint, e.g.
if (a < 0) {
printf("a < 0 !\n"); // <<< set breakpoint here
}
If it's C or C++, simply defining a as volatile should help.
I defined a NO_OP() macro which doesn't do anything and doesn't require the file that's using it to include any header files:
#define NO_OP() {float f = 0; if (f != 0) exit(0);}
I don't know if the compiler will be able to optimize this macro away, but it works for me with MinGW.
It’s not portable, but with MSVC I use __asm nop (surrounded by #ifndef NDEBUG…#endif if the code is likely to remain in place for a while) to insert a literal no-op that I know the compiler won’t touch.
I'm wrestling with the concept of code "order of execution" and so far my research has come up short. I'm not sure if I'm phrasing it incorrectly, it's possible there is a more appropriate term for the concept. I'd appreciate it if someone could shed some light on my various stumbling blocks below.
I understand that if you call one method after another:
[self generateGrid1];
[self generateGrid2];
Both methods are run, but generateGrid1 doesn't necessarily wait for generateGrid2. But what if I need it to? Say generateGrid1 does some complex calculations (that take an unknown amount of time) and populate an array that generateGrid2 uses for it's calculations? This needs to be done every time an event is fired, it's not just a one time initialization.
I need a way to call methods sequentially, but have some methods wait for others. I've looked into call backs, but the concept is always married to delegates in all the examples I've seen.
I'm also not sure when to make the determinate that I can't reasonably expect a line of code to be parsed in time for it to be used. For example:
int myVar = [self complexFloatCalculation];
if (myVar <= 10.0f) {} else {}
How do I determine if something will take long enough to implement checks for "Is this other thing done before I start my thing". Just trial and error?
Or maybe I'm passing a method as parameter of another method? Does it wait for the arguments to be evaluated before executing the method?
[self getNameForValue:[self getIntValue]];
I understand that if you call one method after another:
[self generateGrid1];
[self generateGrid2];
Both methods are run, but generateGrid1 doesn't necessarily wait for generateGrid2. But what if I need it to?
False. generateGrid1 will run, and then generateGrid2 will run. This sequential execution is the very basis of procedural languages.
Technically, the compiler is allowed to rearrange statements, but only if the end result would be provably indistinguishable from the original. For example, look at the following code:
int x = 3;
int y = 4;
x = x + 6;
y = y - 1;
int z = x + y;
printf("z is %d", z);
It really doesn't matter whether the x+6 or the y-1 line happens first; the code as written does not make use of either of the intermediate values other than to calculate z, and that can happen in either order. So if the compiler can for some reason generate more efficient code by rearranging those lines, it is allowed to do so.
You'd never be able to see the effects of such rearranging, though, because as soon as you try to use one of those intermediate values (say, to log it), the compiler will recognize that the value is being used, and get rid of the optimization that would break your logging.
So really, the compiler is not required to execute your code in the order provided; it is only required to generate code that is functionally identical to the code you provided. This means that you actually can see the effects of these kinds of optimizations if you attach a debugger to a program that was compiled with optimizations in place. This leads to all sorts of confusing things, because the source code the debugger is tracking does not necessarily match up line-for-line with the code the compiled code the compiler generated. This is why optimizations are almost always turned off for debug builds of a program.
Anyway, the point is that the compiler can only do these sorts of tricks when it can prove that there will be no effect. Objective-c method calls are dynamically bound, meaning that the compiler has absolutely no guarantee about what will actually happen at runtime when that method is called. Since the compiler can't make any guarantees about what will happen, the compiler will never reorder Objective-C method calls. But again, this just falls back to the same principle I stated earlier: the compiler may change order of execution, but only if it is completely imperceptible to the user.
In other words, don't worry about it. Your code will always run top-to-bottom, each statement waiting for the one before it to complete.
In general, most method calls that you see in the style you described are synchronous, that means they'll have the effect you desire, running in the order the statements were coded, where the second call will only run after the first call finishes and returns.
Also, when a method takes parameters, its parameters are evaluated before the method is called.
The documentation for __assume says "The most common use of __assume is with the default case of a switch statement, as shown in the following example.".
Is there any other case where __assume can lead to more efficient (or even different) code?
When inside of an if / else, isn't the compiler automatically "assuming" what is already known because of the if condition?
I was unable to find any non-trivial examples that show any of above - I hope someone else could.
Consider the following code, compiled with the /Ox switch:
if (1) {
printf("live code\n");
} else {
printf("dead code\n");
}
The optimizer will optimize away the else. Now consider:
int x = 1;
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
The optimizer will once again optimize away the else. Also consider:
int x = 1;
__assume(x != 1);
if (x == 1) {
printf("live code\n");
} else {
printf("dead code\n");
}
The optimizer will optimize away the if this time -- incorrectly so.
To test, build a test program in Release mode (with the /Ox and /Zi options) and look at the generated assembly (Alt+8 in Visual Studio.)
Now consider the above if/else condition being tested in an inline method. In certain contexts, the programmer may know that the inline method is called with a particular value and the optimizer may not have realized this fact. Using __assume at the caller level in the manner illustrated above, just before the inlined method is called, can theoretically help the optimizer.
From Optimization Best Practices (quote from older version):
__assume has been in Visual C++ for
multiple releases, but it has become
much more usable in Visual C++ 2005.
With __assume, a developer can tell
the compiler to make assumptions about
the value of some variable.
For example __assume(a < 5); tells the
optimizer that at that line of code
the variable a is less than 5. Again
this is a promise to the compiler. If
a is actually 6 at this point in the
program then the behavior of the
program after the compiler has
optimized may not be what you would
expect. __assume is most useful prior
to switch statements and/or
conditional expressions.
There are some limitations to
__assume. First, like __restrict, it is only a suggestion, so the compiler
is free to ignore it. Also, __assume
currently works only with variable
inequalities against constants. It
does not propagate symbolic
inequalities, for example, assume(a <
b).
I just want to know what the difference between all the conditional statements in objective-c and which one is faster and lighter.
One piece of advice: stop worrying about which language constructs are microscopically faster or slower than which others, and instead focus on which ones let you express yourself best.
If and case statements described
While statement described
Since these statements do different things, it is unproductive to debate which is faster.
It's like asking whether a hammer is faster than a screwdriver.
The language-agnostic version (mostly, obviously this doesn't count for declarative languages or other weird ones):
When I was taught programming (quite a while ago, I'll freely admit), a language consisted of three ways of executing instructions:
sequence (doing things in order).
selection (doing one of many things).
iteration (doing something zero or more times).
The if and case statements are both variants on selection. If is used to select one of two different options based on a condition (using pseudo-code):
if condition:
do option 1
else:
do option 2
keeping in mind that the else may not be needed in which case it's effectively else do nothing. Also remember that option 1 or 2 may also consist of any of the statement types, including more if statements (called nesting).
Case is slightly different - it's generally meant for more than two choices like when you want to do different things based on a character:
select ch:
case 'a','e','i','o','u':
print "is a vowel"
case 'y':
print "never quite sure"
default:
print "is a consonant"
Note that you can use case for two options (or even one) but it's a bit like killing a fly with a thermonuclear warhead.
While is not a selection variant but an iteration one. It belongs with the likes of for, repeat, until and a host of other possibilities.
As to which is fastest, it doesn't matter in the vast majority of cases. The compiler writers know far more than we mortal folk how to get the last bit of performance out of their code. You either trust them to do their job right or you hand-code it in assembly yourself (I'd prefer the former).
You'll get far more performance by concentrating on the macro view rather than the minor things. That includes selection of appropriate algorithms, profiling, and targeting of hot spots. It does little good to find something that take five minutes each month and get that running in two minutes. Better to get a smaller improvement in something happening every minute.
The language constructs like if, while, case and so on will already be as fast as they can be since they're used heavily and are relative simple. You should be first writing your code for readability and only worrying about performance when it becomes an issue (see YAGNI).
Even if you found that using if/goto combinations instead of case allowed you to run a bit faster, the resulting morass of source code would be harder to maintain down the track.
while isn't a conditional it is a loop. The difference being that the body of a while-loop can be executed many times, the body of a conditional will only be executed once or not at all.
The difference between if and switch is that if accepts an arbitrary expression as the condition and switch just takes values to compare against. Basically if you have a construct like if(x==0) {} else if(x==1) {} else if(x==2) ..., it can be written much more concisely (and effectively) by using switch.
A case statement could be written as
if (a)
{
// Do something
}
else if (b)
{
// Do something else
}
But the case is much more efficient, since it only evaluates the conditional once and then branches.
while is only useful if you want a condition to be evaluated, and the associated code block executed, multiple times. If you expect a condition to only occur once, then it's equivalent to if. A more apt comparison is that while is a more generalized for.
Each condition statement serves a different purpose and you won't use the same one in every situation. Learn which ones are appropriate for which situation and then write your code. If you profile your code and find there's a bottleneck, then you go ahead and address it. Don't worry about optimizing before there's actually a problem.
Are you asking whether an if structure will execute faster than a switch statement inside of a large loop? If so, I put together a quick test, this code was put into the viewDidLoad method of a new view based project I just created in the latest Xcode and iPhone SDK:
NSLog(#"Begin loop");
NSDate *loopBegin = [NSDate date];
int ctr0, ctr1, ctr2, ctr3, moddedNumber;
ctr0 = 0;
ctr1 = 0;
ctr2 = 0;
ctr3 = 0;
for (int i = 0; i < 10000000; i++) {
moddedNumber = i % 4;
// 3.34, 1.23s in simulator
if (moddedNumber == 0)
{
ctr0++;
}
else if (moddedNumber == 1)
{
ctr1++;
}
else if (moddedNumber == 2)
{
ctr2++;
}
else if (moddedNumber == 3)
{
ctr3++;
}
// 4.11, 1.34s on iPod Touch
/*switch (moddedNumber)
{
case 0:
ctr0++;
break;
case 1:
ctr1++;
break;
case 2:
ctr2++;
break;
case 3:
ctr3++;
break;
}*/
}
NSTimeInterval elapsed = [[NSDate date] timeIntervalSinceDate:loopBegin];
NSLog(#"End loop: %f seconds", elapsed );
This code sample is by no means complete, because as pointed out earlier if you have a situation that comes up more times than the others, you would of course want to put that one up front to reduce the total number of comparisons. It does show that the if structure would execute a bit faster in a situation where the decisions are more or less equally divided among the branches.
Also, keep in mind that the results of this little test varied widely in performance between running it on a device vs. running it in the emulator. The times cited in the code comments are running on an actual device. (The first time shown is the time to run the loop the first time the code was run, and the second number was the time when running the same code again without rebuilding.)
There are conditional statements and conditional loops. (If Wikipedia is to be trusted, then simply referring to "a conditional" in programming doesn't cover conditional loops. But this is a minor terminology issue.)
Shmoopty said "Since these statements do different things, it is nonsensical to debate which is faster."
Well... it may be time poorly spent, but it's not nonsensical. For instance, let's say you have an if statement:
if (cond) {
code
}
You can transform that into a loop that executes at most one time:
while (cond) {
code
break;
}
The latter will be slower in pretty much any language (or the same speed, because the optimizer turned it back into the original if behind the scenes!) Still, there are occasions in computer programming where (due to bizarre circumstances) the convoluted thing runs faster
But those incidents are few and far between. The focus should be on your code--what makes it clearest, and what captures your intent.
loops and branches are hard to explain briefly, to get the best code out of a construct in any c-style language depends on the processor used and the local context of the code. The main objective is to reduce the breaking of the execution pipeline -- primarily by reducing branch mispredictions.
I suggest you go here for all your optimization needs. The manuals are written for the c-style programmer and relatively easy to understand if you know some assembly. These manuals should explain to you the subtleties in modern processors, the strategies used by top compilers, and the best way to structure code to get the most out of it.
I just remembered the most important thing about conditionals and branching code. Order your code as follows
if(x==1); //80% of the time
else if(x==2); // 10% of the time
else if(x==3); //6% of the time
else break;
You must use an else sequence... and in this case the prediction logic in your CPU will predict correctly for x==1 and avoid the breaking of your pipeline for 80% of all execution.
More information from intel. Particularly:
In order to effectively write your code to take advantage of these rules, when writing if-else or switch statements, check the most common cases first and work progressively down to the least common. Loops do not necessarily require any special ordering of code for static branch prediction, as only the condition of the loop iterator is normally used.
By following this rule you are flat-out giving the CPU hints about how to bias its prediction logic towards your chained conditionals.