taking the address of temporary object - xcode

I'm developping on many platforms, today I have a problem with iOS and xCode,
I'm upadating some projects to the last xCode 4.3.2 (Apple LLVM compiler 3.1)
since few time a warning has become an error: "taking the address of temporary object"
unfortunately I used many of that, see my example :
float dist = Vector3Dlength(&Vector3D(pos2 - pos1));
to avoid to create a temporary var and produce a new line of code (although this one is created on the stack by the compiler)
I know the mistakes that can lead since 10 years of coding like that :) but I WANT to continue like that...
someone have a suggestion to avoid this error without having to edit the code ? (with the new xCode 4.3.2 (Apple LLVM compiler 3.1))

You'll need to change your code, you can't take an address of something that is not an lvalue, and that temporary isn't one.
Change your code to take a const reference to Vector3D instead. This will not cost you a copy, and is well-defined behavior.
float Vector3Dlength(Vector3D const& pvect) {
return sqrt(pvect.x * pvect.x ...);
}
...
float dist = Vector3Dlength(Vector3D(pos2 - pos1));

Related

Ridiculous amount of warnings in xcode 6 beta 7

In Xcode 6 beta 7, my warnings are divided into two sections, for example if one is called "my app" the other would be called "my app project". I have fixed all warnings I have received in the "my app" section ( there were only 3-4). On the "my app project" section however, I have over 42,000 warnings! It has been this way since before I even wrote any code and created my empty project. I always assumed this was a beta issue but I would like to know if everyone else is experiencing the same thing. I am unable to even look at what the problems are as Xcode freezes when I try due to the overwhelming number of warnings.
The release notes provide some details into the errors, seems to be the evolution of Swift:
http://adcdownload.apple.com//Developer_Tools/xcode_6_beta_7_apzr94/xcode_6__beta_7_release_notes.pdf
From the release notes:
Swift Language
• A large number of Foundation, UIKit, CoreData, SceneKit, SpriteKit, Metal APIs have been audited for optional conformance, removing a significant number of implicitly unwrapped optionals from their interfaces. This clarifies the nullability of their properties, arguments and return values of their methods. This is an ongoing effort that started shipping in beta 5.
These changes replace T! with either T? or T depending on whether the value can be null or not null, respectively. If you find a case that was changed incorrectly, please file a radar and include the tag ‘#IUO’ in the subject line. Please do not file feature requests about APIs that are still marked as T!, we know about them.
If you encounter a method for which the return value is incorrectly considered non-nullable, or a property that is incorrectly considered non-nullable, you can work around the problem by immediately wrapping the result in an optional:
var fooOpt: NSFoo? = object.reallyMightReturnNil()
if let foo = fooOpt { ... }
I haven't had any issues like that in any of the releases including Xcode 6 Beta 7. Each beta release I usually end up with about 100 or so errors due to changes in syntax but they only take half an hour or so to go through and resolve.

Preprocessor macro to remove code if compiled after a certain date

I would like three lines of code not to be included if compiled after a certain date.
The reason being is they provide backwards compatibility. To support a staggered release between client and embedding it is required to be there now.
Once the next software release comes along this support is to be dropped to force customers to upgrade the embedded software. Since this is a few months away there is risk of these lines being forgotten.
So ideally I would like a
#if __DATE__ > MyDate
code here
#endif
or something equivalent.
Is there any way of doing this?
*The code is compiled with GCC
This solution is specifically for Windows platform and is something I use in production.
I exploit the environment variable %DATE%, and in a batch file used to launch my IDE, I have VA_CURRENT_DATE=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2% (which transforms to an ISO8601 date for my specific locale).
Then in my preprocessor definitions for my project I define VA_BUILD_DATE to VA_CURRENT_DATE
Then I have some code like:
long day = VA_BUILD_DATE;
long year = day / 10000;
day -= year * 10000;
long month = day / 100;
day -= month * 100;
You can't do this with __DATE__, because it expands to a string constant, and string constants can't be used in #if. Also, setting a fixed date is a bad idea, because you may need to do bug-fix releases to the older version that should preserve the backward compatibility.
(Do you really need to drop backward compatibility? If it's only three lines of code, consider just keeping them around forever. Your customers will not thank you for "forcing them to upgrade.")
The good way to do this sort of thing is via your version control system. You should be maintaining a branch for each release anyway, so write your code like this:
#ifdef BACKWARD_COMPAT_VERSION_1_0
compatibility code here
#endif
and then change the Makefile on the release branch, only, to include -DBACKWARD_COMPAT_VERSION_1_0 in your CFLAGS.
Now I am running the risk of not answering your question directly. But I'd take the risk and suggest you NOT to do so. How many times does a project get released on time? The date is, too prone to change. And you never know that.
Why not use the version of your project instead?
// Only defined in old projects that you want this legacy code in.
#ifdef OLD__VERSION
code here
#endif
Unfortunately this won't work as __DATE__ produces a string in the form "Sep 5 2013", which is useless for comparison.
Ideally the compiler should support a constant like __DATEFLAT__ which produces an integer like 20130905, which would be ideal for such as task. However this doesn't exist.

list insert returns void for c++11, why?

First a bit of background:
I've been writing for a programming assignment, which requires that I parse a text grammar file. In this, I need to replace a placeholder string in a std::list<string> with its corresponding expansion (the string represents a sentence).
I iterate through the list, and erase the matching string with:
itr = ls.erase(itr)
where itr is an iterator and ls is my std::list<string>
I then insert the expansion like
itr = ls.insert(itr, other.begin(), other.end());
where other is a container storing the expansion.
My problem is that the previous line apparently doesn't work. It's supposedly valid c++11 syntax, and I would really like for the iterator to point to the start of what I just inserted. But I get compile errors, as insert apparently returns void.
I've checked with cplusplus.com, and as far as i can see, I don't see anything wrong with how I'm using it. The standard (or at least the one that i can see) states:
iterator insert(const_iterator position, InputIterator first,
InputIterator last);
I'm compiling using g++ (4.8.1) with the -std=c++11 flag but when I look at stl_list.h in (gcc-directory)/include/c++/4.8.1/bits i see:
void
insert(iterator __position, _InputIterator __first,_InputIterator __last)
Is this just because gcc hasn't fully implemented the c++11 library? Did they overlook this bit? Doesn't seem hard to do, and all the other insert functions surrounding it return an iterator.
I know I can work around this without too much hassle, but still it would be nice to know what's going on.
Thanks!
edit apparently this answers my question. Sorry to bother you, pity I couldn't find it before.
Libstdc++ just hadn't been updated to return an iterator from that function yet.
That was fixed on the subversion trunk two months ago by this patch: http://gcc.gnu.org/ml/libstdc++/2013-07/msg00000.html
That change was made after the GCC 4.8.1 release, and I don't think the change has been backported to the 4.8 branch anyway.

Where Is gcvt or gcvtf Defined in gcc Source Code?

I'm working on some old source code for an embedded system on an m68k target, and I'm seeing massive memory allocation requests sometimes when calling gcvtf to format a floating point number for display. I can probably work around this by writing my own substitute routine, but the nature of the error has me very curious, because it only occurs when the heap starts at or above a certain address, and it goes away if I hack the .ld linker script or remove any set of global variables (which are placed before the heap in my memory map) that add up to enough byte size so that the heap starts below the mysterious critical address.
So, I thought I'd look in the gcc source code for the compiler version I'm using (m68k-elf-gcc 3.3.2). I downloaded what appears to be the source for this version at http://gcc.petsads.us/releases/gcc-3.3.2/, but I can't find the definition for gcvt or gcvtf anywhere in there. When I search for it, grep only finds some documentation and .h references, but not the definition:
$ find | xargs grep gcvt
./gcc/doc/gcc.info: C library functions `ecvt', `fcvt' and `gcvt'. Given va
lid
./gcc/doc/trouble.texi:library functions #code{ecvt}, #code{fcvt} and #code{gcvt
}. Given valid
./gcc/sys-protos.h:extern char * gcvt(double, int, char *);
So, where is this function actually defined in the source code? Or did I download the entirely wrong thing?
I don't want to change this project to use the most recent gcc, due to project stability and testing considerations, and like I said, I can work around this by writing my own formatting routine, but this behavior is very confusing to me, and it will grind my brain if I don't find out why it's acting so weird.
Wallyk is correct that this is defined in the C library rather than the compiler. However, the GNU C library is (nearly always) only used with Linux compilers and distributions. Your compiler, being a "bare-metal" compiler, almost certainly uses the Newlib C library instead.
The main website for Newlib is here: http://sourceware.org/newlib/, and this particular function is defined in the newlib/libc/stdlib/efgcvt.c file. The sources have been quite stable for a long time, so (unless this is a result of a bug) chances are pretty good that the current sources are not too different from what your compiler is using.
As with the GNU C source, I don't see anything in there that would obviously cause this weirdness that you're seeing, but it's all eventually a bunch of wrappers around the basic sprintf routines.
It is in the GNU C library as glibc/misc/efgcvt.c. To save you some trouble, the code for the function is:
char *
__APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf)
FLOAT_TYPE value;
int ndigit;
char *buf;
{
sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value);
return buf;
}
The directions for obtain glibc are here.

Xcode equivalent of ' __asm int 3 / DebugBreak() / Halt?

What's the instruction to cause a hard-break in Xcode? For example under Visual Studio I could do '_asm int 3' or 'DebugBreak()'. Under some GCC implementations it's asm("break 0") or asm("trap").
I've tried various combos under Xcode without any luck. (inline assembler works fine so it's not a syntax issue).
For reference this is for an assert macro. I don't want to use the definitions in assert.h both for portability, and because they appear to do an abort() in the version XCode provides.
John - Super, cheers. For reference the int 3 syntax is the one required for Intel Macs and iPhone.
Chris - Thanks for your comment but there are many reasons to avoid the standard assert() function for codebases ported to different platforms. If you've gone to the trouble of rolling your own assert it's usually because you have additional functionality (logging, stack unwinding, user-interaction) that you wish to retain.
Your suggestion of attempting to replace the hander via an implementation of '__assert" or similar is not going to be portable. The standard 'assert' is usually a macro and while it may map to __assert on the Mac it doesn't on other platforms.
http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/090_Running_Programs/chapter_11_section_3.html
asm {trap} ; Halts a program running on PPC32 or PPC64.
__asm {int 3} ; Halts a program running on IA-32.
You can just insert a call to Debugger() — that will stop your app in the debugger (if it's being run under the debugger), or halt it with an exception if it's not.
Also, do not avoid assert() for "portability reasons" — portability is why it exists! It's part of Standard C, and you'll find it wherever you find a C compiler. What you really want to do is define a new assertion handler that does a debugger break instead of calling abort(); virtually all C compilers offer a mechanism by which you can do this.
Typically this is done by simply implementing a function or macro that follows this prototype:
void __assert(const char *expression, const char *file, int line);
It's called when an assertion expression fails. Usually it, not assert() itself, is what performs "the printf() followed by abort()" that is the default documented behavior. By customizing this function or macro, you can change its behavior.
__builtin_trap();
Since Debugger() is depreciated now this should work instead.
https://developer.apple.com/library/mac/technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391-CH1-SECCONTROLLEDCRASH
For posterity: I have some code for generating halts at the correct stack frame in the debugger and (optionally) pausing the app so you can attach the debugger just-in-time. Works for simulator and device (and possibly desktop, if you should ever need it). Exhaustively detailed post at http://iphone.m20.nl/wp/2010/10/xcode-iphone-debugger-halt-assertions/
I found the following in an Apple Forum:
Xcode doesn't come with any symbolic breaks built in - but they're
quick to add. Go to the breakpoints window and add:
-[NSException raise]
kill(getpid(), SIGINT);
Works in the simulator and the device.
There is also the following function that is available as cross platform straight Halt() alternative:
#include <stdlib.h>
void abort(void);
We use it in our cross platform engine for the iPhone implementation in case of fatal asserts. Cross platform across Nintendo DS/Wii/XBOX 360/iOS etc...

Resources