What do I need to do to use tgmath on iOS? - ios

I'm compiling my first project with 64 bit support enabled. I'm running into a bunch of compiler warnings about implicit conversions to float. This is happening because I'm using fabsf() and assigning the result to a CGFloat (which is a double, not float on the new 64 bit architecture).
According to the answer on this question:
CGFloat-based math functions?
I just need to #include <tgmath.h> to solve this problem and probably change fabsf to fabs. I have at least one file where this doesn't seem to be helping. I still get the warning: implicit conversion loses floating-point precision 'double' to 'CGFloat' aka (float). Here's the line that generates that warning:
CGFloat deltaX = fabs(item.center.x-point.x);
Has anyone else run across this? How did you solve it? I'd rather not disable this warning or litter my code with a ton of typecasts.

I guess, you are using CGPoint types, so the conversion doesn't occur within fabs(DOUBLE -> FLOAT), but on assignment CGFloat = DOUBLE. That's probably because compiler used fabs from math.h which operates on doubles.
Problem with math.h is that it's internally imported by OSX headers (carbon if I remember correctly), so I guess some iOS header might also do that. After quick look, it seems that basic set of frameworks doesn't import math.h, so probably you should look for it being manually imported. In case it's imported internally by some system libs, you'll probably won't be able to use those libs and tgmath in a single implementation file.
If you want to check if there are some math.h dependencies, you can use a dirty trick to prevent it's inclusion - add this line to a file (or better on top of prefix file):
#define __MATH_H__

I was able to get the tgmath.h functions to work by including the header at the top of my PCH file.
At some point (read: Xcode update) I had to start disabling Modules to get this to work. The details of such are in the question Dima links to below.

Related

How are the various similar simd_ functions different from each other?

In typical Apple fashion, there's no documentation (and what little there borders on trolling). For example, what is simd_precise_normalize(_:)? You’d be forgiven for thinking it was a slower, more precise normalization than simd_fast_normalize(_:). But then why does simd_normalize(_:) exist?
Why is there simd_cross(simd_float3, simd_float3) and cross(SIMD3<Float>, SIMD3<Float>) when typealias simd_float3 = SIMD3<Float>?
And what about the Swift operator overloads on simd_float3?
I've written a bug to Apple about it, but does anyone know?
But then why does simd_normalize(_:) exist?
This comment explains it. simd_normalize is equivalent to simd_precise_normalize unless you are compiling with -ffast-math specified, in which case it is equivalent to simd_fast_normalize. I never used swift only objective-c, but it’s possible there’s equivalent option somewhere in compiler switches or xcode project settings.
Why is there simd_cross(simd_float3, simd_float3) and cross(SIMD3, SIMD3)
I think they are equivalent. Note that comments in the header discuss both C-style API like simd_cross(x,y) and C++ API simd::cross(x,y). It could be that in Swift both are available for some of these functions.

Prevent ArmClang to add calls to Standard C library

I am evaluating Keil Microvision IDE on STM32H753.
I am doing compiler comparison between ARMCC5 and AC6 in the different optimisation levels. AC6 is based on Clang.
My code is not using memcpy and I have unchecked "Use MicroLIB" in the project settings , However a basic byte per byte copy loop in my code is replaced by a memcpy with AC6 (only in "high" optimisation levels). It doesn't happen with ARMCC5.
I tried using compilation options to avoid that, as described here: -ffreestanding and -disable-simplify-libcalls, at both compiler and linker levels but it didn't change (for the second option, I get an error message saying that the option is not supported).
In the ARMCLANG reference guide i've found the options -nostdlib -nostdlibinc that prevent (??) the compiler to use any function of a standard lib.
However I still need the math.h function.
Do you know how to prevent clang to use functions from the Standard C Lib that are not explicitely called in the code ?
EDIT: here is a quick and dirty reproduceable example:
https://godbolt.org/z/AX8_WV
Please do not discuss the quality of this example, I know it is dumb !!, I know about memset, etc... It is just to understand the issue
gcc know a lot about the memcpy, memset and similar functions and even they are called "the builtin functions". If you do not want those functions to be used by default just use the command line option -fno-builtin
https://godbolt.org/z/a42m4j

Add #include's to the headers of a program using llvm clang

I need to add headers to an already existing program by transforming it with LLVM and Clang.
I have used clang's rewriter to accomplish a similar thing in the changing function names and arguments, etc.
But the header files aren't present in clang's AST. I already know we need to use PPCallbacks (https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html) but I am in dire need of some examples on how to make it work with the rewriter if at all possible.
Alternatively, adding a #include statement just before the first
using namespace <namespace>;
Also works. I would like to know an example of this as well.
Any help would be appreciated.
There is a bit of confusion in your question. You need to understand in details how the preprocessor works. Be aware that most of C++ compilation happens after the preprocessing phase (so most C++ static analyzers work after that phase).
In other words, the C++ specification (and also the C specification) defines first what is preprocessing, and then what is the syntax and the semantics of the preprocessed form.
In other words, when compiling foo.cc your compiler see the preprocessed form foo.ii that you could obtain with clang++ -C -E foo.cc > foo.ii
In the 1980s the preprocessor /lib/cpp was a separate program forked by the compiler (and some temporary foo.ii was sitting on the disk and removed at end of compilation). Today, it is -for performance reasons- some initial processing done inside the compiler. But you could reason as if it was still separate.
Either you want to alter the Clang compiler, and it deals (like every other C++ compiler or C++ static analyzer) mostly with the preprocessed form. Then you don't want to add new #include-s, but you want to alter the flow of AST given to the compiler (after preprocessing), and that is a different question: you then want to add some AST between existing AST elements (independently of any preprocessor directives).
Or you want to automatically change the C++ source code. The hard part is determining what you want to change and at what place. I suppose that you have used complex stuff to determine that a #include <vector> has to be inserted after line 34 of file foo.cc. Once you've got that information (and getting it is the hard thing), doing the insertion is pretty trivial. For example, you could read every C++ source line, and insert your line when you have read enough lines.

Xcode 5 weird errors

Something strange is going on with my Xcode 5. All of a sudden I'm getting Undeclared Identifier errors for all the values in my Constants.h file, which is imported in my Prefix.pch file.
Two things are weird here:
This hasn't happened before.
When I do build and run, the build succeeds and the app runs with no problems.
I tried restarting Xcode and the simulator, and even restarting the whole machine. No luck.
What's going on? How can I get rid of these false errors?
EDIT following rmaddy's request. The error is Use of undeclared identifier kOffsetFromTop (for example, there are other similar errors with different constants.)
I don't really want to post my entire constants file, but the constant in question is defined like this:
static int const kOffsetFromTop = 20;
When this happens I normally do the following
Comment out the import from the .pch
Clean all ⌘⌥⇧K
Delete derived data
Build
Then uncomment the import from the .pch and build again. I'm not sure which step is actually sorting the issue but this normally gets me going again.
Multiple points here :
You have a warning, not an error. A warning is just that, it warns you but does not prevent the code to compile. That is just to warning you that something is odd or unexpected, or to tell you that what you wrote may not be actually what you were intended, because the compiler finds it odd or not standard.
You didn't have the warning before probably because it wasn't activated by default in previous versions of Xcode. The latest version of Xcode5 activates more warnings (which is a good thing, as it warns you about more things that could go wrong in your code and encourage you to fix them), hence this new one you have but didn't have before.
As I understand what you describe, tour usage of a constant is incorrect (and that's probably why Xcode emits a warning).
The correct way to declare a constant that you want to be accessible from multiple files is to:
Declare it (define its existence and type) in a header (or in your pch) like this: extern <type> const <name>;
And define it (give it a value) only in one implementation file (like your main.m, your AppDelegate.m, some Constants.m file, whatever) like this: <type> const <name> = <value>
Some details and reminders about constants declaration (also valid in standard C)
You use static <type> const <name> = <value>; in an implementation file only, when the constant is local to the file and does not need to be used by other files. In that case, you declare it typically in the .m file in which you will use it, and other files won't have access to it (which is quite what the static keyword means, actually (making the constant attached/local to the file).
In that matter, you should never declare a constant that way in a header file (and especially not in your .pch file), because header (and pre-compiled header) files will be included multiple times. If you do that, this would declare as many independent constants as the number of implementation files you include your headers into (this has evil side effects especially for pointers/objects, for exemple declaring an NSString* const that way -- for, say, using it as a notification name of error domain -- will create multiple string constants, with the same value but different addresses, which will probably not behave like you will expect)
When you need to declare a constant that you need to use / be accessible from multiple implementation files, so declaring this constant in a header file so that it is known to all implementation fiels that includes this header, you need to only declare it in the header, and not making it static (at this would run against the purpose of having the same constant for all files instead of multiple independent instances of the constant) but instead indicate extern to let the compiler know that its definition (value) is set elsewhere. Hence the solution given above.

*Sometimes* get an error when assigning to a constant in Delphi

I am using Delphi 2007 with all patches and updates.
I have a file which is used by two different projects. In that file is a procedure, which I will simplify as follows:
procedure MyProcedure;
const
UniqueValue: integer = 0;
begin
//some code
Inc(UniqueValue);
//some more code
end;
The Inc() command should fail, because you cannot assign to a constant. In one project, I get an error to that effect (I'll call that project "Accurate"). In the other project, I don't get any errors (I'll call it "Bogus"). I also don't get any warnings. I can't figure out why the compiler lets this incorrect code through.
Here's what I've tried in project Bogus:
1 - Introduce an obvious error, like typing "slkdjflskdjf" in the middle of a line
Result: I get an error,which proves that it is really trying to compile this file.
2 - Delete the .DCU, and rebuild the project
Result: The .DCU is re-generated, again proving that the project is truly compiling this erroneous code.
Does anyone have thoughts on why this behavior would occur? And more specifically, why it would occur in one project but not another? Is there some obscure compiler option to permit assigning to constants?
One final note: Both projects are converted from Delphi 5. Under Delphi 5 with similar code, they both compile fine.
Edit: Thanks for all your help. After changing the assignable typed constants directive, I can get consistent behavior across both projects. I learned something new today...
There is an option for this called "Assignable typed constants" in Compiler Options. It can also be enabled with "{$J+}" in your code.
Could it be that those projects differ in the setting of the $J compiler directive?
I'd suggest to check the Project Options, section Compiler and see if you can spot any differences. Maybe you have option Assignable typed constants enabled in the Bogus project.
As others have said it's almost certainly the {$J+} directive.
If you have a diff tool you can compare the project files to see how they differ - they're just text files - to solve similar problems in the future.

Resources