Error because of size of function in Objective-C - iphone

I am having a weird error message when i try to build my application for device:
{standard input}:3884:invalid offset, value too big (0x00000408)
Command /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/gcc-4.2 failed with exit code 1
the class that issued this error message contains a function that has a huge switch statement with contains other switch statements in its cases. It is almost 1200 lines long!!
When i commented this function out the compilations was complete. So i predict this is whats meant by " value too big" in the error message above, correct me if am wrong.
Now how do i get over this limitation? I am thinking of a way to break my function into different parts and implement them in categories of the class in different files. But am not sure it is gonna be that easy as the function only contains switch statements within a huge statement. I will look at this further but does any one else have any other suggestion?
Cheers
AF

Firstly, if you're using xcodebuild directly try building via the IDE as some reports seem to suggest this can help, unlikely though that may sound.
Secondly, if this is a compiler bug (it sounds like it is and there are quite a few similar reports on the hyperinternetweb), you could also try switching to using LLVM (via your projects "Compiler version" settings) and see if that makes a difference.
Finally, you could simply avoid the issue by using an if/else construct instead, painful though that will be.
UPDATE
To try out LLVM (instead of gcc), select your project's build target from the "Targets" section in the Groups & Files area, alt-click and select "Get info". In the window that appears then select the Build tab (if it's not already selected) and scroll down to the "C/C++ Compiler Version" setting within the Compiler Version category. You then then choose to use "LLVM compiler" instead of gcc.

Related

Cocos2D and Xcode 4 - Compiler errors using templates

I just installed the cocos2d templates in Xcode 4. When I create a new project from the template and run it, it shows around 30 compiler errors. Even without making any changes to the template. Do you have any idea what is wrong?
Please add some more information about errors, but it looks like you forgot to add to your project OpenGLES and QuartzCore frameworks. I could be wrong...
I just spent 10 or 15 minutes plus fixing a bunch of errors in this situation, so i will guess: moving to Xcode 4.X caused many problems for cocos2d projects (including Kobold2D) and most of them require putting "(unsigned int)" in front of an argument in a list of arguments to a 'string with format' type operation creating mostly debug type output. usually the argument in question is "self", but sometimes just other "types" that resolve to (or can) unsigned ints. in a few cases I had no arguments but a reference to the error string to %#; these required adding a ", self" between the end of string and the close paren. in about 5 to 10% of cases, "fixits" were provided to automate the correction (usually changing the format character to match the argument). Hope this helps! Happy to provide examples if this actually helps anyone.

How to evaluate/watch a variable or method whilst debugging in XCode

I come from a Delphi and .Net background and have just started iPhone development. I just came across a problem whilst debugging.
I had the following code:
if ([displayText rangeOfString:#"."].location != NSNotFound) .....etc
I wanted to evaluate this whilst I was debugging but could not work out how to do it. I found the Expressions window and entered the below but nothing happened:
[displayText rangeOfString:#"."].location
As I'm used to Delphi & .Net (and I know XCode is a different product) its very easy to stick in variables, methods etc into a watch window and then see the result but I cannot see how to do this in XCode. Please can you tell me how I evaluate things whilst debugging??
Thanks
In your case, what you would do is at the debugger is type:
p (NSRange)[displayText rangeOfString:#"."]
You can print out the value of objects with po, but things like C structures have to be printed out with "p" and you have to cast the return types from ObjC calls to the correct struct type.
Also, just putting this in the Expressions window should result in a value:
(NSRange)[displayText rangeOfString:#"."]
In both cases you will see the whole NSRange struct, with location and length.
You can watch variables by going in the debugging drop down in the main menu on top and selecting watch variable. You can also right click and you should see the option "watch variable." Alternatively you can hover your mouse over the desired variable while stepping through your code to see its value at that time

In Eclipse, how do I see the input to Assert.assertEquals when it fails?

I'm not much of an Eclipse guru, so please forgive my clumsiness.
In Eclipse, when I call Assert.assertEquals(obj1,obj2) and that fails, how do I get the IDE to show me obj1 and obj2?
I'm using JExample, but I guess that shouldn't make a difference.
Edit: Here's what I see:
(source: yfrog.com)
.
Comparison with failure trace is not a easy task when your object is a little bit complex.
Comparison with debugger is useful if you have not redefined toString(). It remains still very tedious as solution because you should inspect with your eyes each objects from both sides.
Junit Eclipse plugin offers a option when there is a failure : "Compare actual With Expected TestResult". The view is close enough to classic content comparison tools :
Problem is that it is avaiable only when you writeassertEquals() with String objects (in the screenshot, we can see that the option in the corner is not proposed with no String class) :
You may use toString() on your object in assertion but it's not a good solution :
firstly, you correlate toString() with equals(Object)... modification of one must entail modification of the other.
secondly, the semantic is not any longer respected. toString() should return a useful method to debug the state of one object, not to identify an object in the Java semantic (equals(Object)).
According to me, I think that the JUnit Eclipse plugin misses a feature.
When comparison fails, even when we compare not String objects, it should offer a comparison of the two objects which rely on their toString() method.
It could offer a minimal visual way of comparing two unequals objects.
Of course, as equals(Object) is not necessarily correlated to toString(), highlighted differences should be studied with our eyes but it would be already a very good basis and anyway, it is much better than no comparison tool.
If the information in the JUnit view is not enough for you, you can always set a exception breakpoint on, for example, java.lang.AssertionError. When running the test, the debugger will stop immediately before the exception is actually being thrown.
Assert.assertEquals() will put the toString() representation of the expected and actual object in the message of the AssertionFailedError it throws, and eclipse will display that in the "failure trace" part of the JUnit view:
(source: ibm.com)
If you have complex objects you want to inspect, you'll have to use the debugger and put a breakpoint inside Assert.assertEquals()
What are you seeing?
When you do assertTrue() and it fails, you see a null.
But when you do assertEquals, it is supposed to show you what it expected and what it actually got.
If you are using JUnit, mke sure you are looking at the JUnit view and moving the mouse to the failed test.
FEST Assert will display comparison dialog in case of assertion failure even when objects you compare are not strings. I explained it in more detail on my blog.
If what you are comparing is a String then you can double click stack element and it will popup a dialog showing the diff in eclipse.
This only works with Strings though. For the general case the only way to see the real reason is to install a breakpoint and step into it.

MS VS-2005 Compiler optimization not removing unused/unexecuted code

I have a workspace built using MS-Visual Studio 2005 with all C code.In that i see many functions which are not called but they are still compiled(they are not under any compile time macro to disable them from compiling).
I set following optimization settings for the MS-VS2005 project to remove that unused code:-
Optimization level - /Ox
Enable whole program optimization - /GL
I tried both Favor speed /Ot and Favor Size /Os
Inspite of all these options, when i see the linker generated map file, I see the symbols(unsed functions) names present in the map file.
Am I missing something? I want to completely remove the unused code.
How do I do this?
The compiler compiles C files one-at-a-time. Therefore, while compiling a C-file that does contains an unused function, the compiler cannot be sure that it will not be called from another file and hence it will compile that function too. However, if that function were declared as static (file-scope), then the compiler would know it is not used and hence remove it.
Even with whole program optimization, I think it would still not be done since the compilation could be for a library.
Linkers do something similar to what you are looking for. If your code links against a library containing multiple objects, then any objects that do not contain functions used by your code (directly or indirectly) would not be included in the final executable.
One option would be to separate your code into individual libraries and object files.
PS - This is just my guess. The behavior of the compiler (with whole program optimization) or linker essentially depends on the design choices of that particular compiler or linker
On our projects we have a flag set under the project properties\Linker\Refrences. We set it to Eliminate Unreferenced Data (/OPT:REF), according to the description this is supposed to remove function calls or data that are never used. I am just going by the description, I have never tested this or worked with it. But I just happened to see it within the last hour and figured it might be something you could try.

iPhone -mthumb-interlinking

os i figured out how to use the -mthumb and -mno-thumb compiler flag and more or less understand what it's doing.
But what is the -mthumb-interlinking flag doing? when is it needed, and is it set for the whole project if i set 'compile for thumb' in my project settings?
thanks for the info!
Open a terminal and type man gcc
Do you mean -mthumb-interwork ?
-mthumb-interwork
Generate code which supports calling between the ARM and Thumb
instruction sets. Without this option the two instruction sets
cannot be reliably used inside one program. The default is
-mno-thumb-interwork, since slightly larger code is generated when
-mthumb-interwork is specified.
If this is related to a build configuration, you should be able to set it separately for each configuration "such as Release or Debug".
Why do you want to change these settings? I know using thumb instructions save some memory but will it save enough to matter in this case?
my application uses both, thumb and vfp code but i never specifically
set -thumb-interwork flag.. how is that possible?
According to man page, without that flag the two instructions sets
cannot be reliably used inside one program.
It says "reliably"; so without that option, it seems they still can be mixed within a single program but it might be "unreliably". I think normally mixing both instructions sets works, the compiler is smart enough to figure out when it has to switch from one set to another one. However, there might be border cases the compiler just doesn't understand correctly and it might fail to see that it should switch instruction sets here, causing the application to fail (most likely it will crash). This option generates special code, so that no matter what your code does, the switching always happens correctly and reliably; the downside is that this extra code is needed for every global visible function and thus increases the binary side (I have no idea if it also might slow down function calls a little bit, I personally would expect that).
Please also note the following two settings:
-mcallee-super-interworking
Gives all externally visible functions in the file being
compiled an ARM instruction set header
which switches to Thumb mode before executing the rest of
the function. This allows these
functions to be called from non-interworking code.
-mcaller-super-interworking
Allows calls via function pointers (including virtual
functions) to execute correctly regardless
of whether the target code has been compiled for
interworking or not. There is a small overhead
in the cost of executing a function pointer if this option
is enabled.
Though I think you only need those, when building libraries to be used with other projects; but I don't know for sure. The GCC thumb handling is definitely "underdocumented".