Strange "selector mangling" in Objective-C method with Boolean arguments - objective-c

I need to recover method names dynamically, via reflection calls at runtime. But get strange results for some.
My TestClass contains a method like:
- (void)testMethod6_NSRect:(NSRect)a1 int:(int)a2 int:(int)a3 bool:(Boolean)a4 {
...
}
When enumerating the above classes methods using class_copyMethodList() and fetching the method selectors via method_getName(), I get:
"testMethod6_NSRect:int:int:_Bool:"
Thus, the selector was rewritten somehow (by gcc?) to make "_Bool" from "bool". As far as I tested yet, this seems to be done only for a "bool" selector-part - if I change it to int:(int), as in:
- (void)testMethod1_int:(int)a1 int:(int)a2 int:(int)a3 int:(int)a4 {
...
}
I get the expected:
"testMethod1_int:int:int:int:"
Q:
Does anyone know the rules or a pointer to where I could find them for this "selector rewriting", or am I missing something? Is this only done for "bool"?
I also need to know if this behavior is depending on the gcc-version, osx-version or runtime library version.
I am using (gcc --version):
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)
on a (uname -a)
10.8.0 Darwin Kernel Version 10.8.0:

The problem lies in an ugly piece of preprocessor magic in the C99 standard header <stdbool.h>:
#define bool _Bool
C99 defines a type named _Bool which behaves like C++'s bool type. The define is there to be able to use it in C but with the C++ identifier.
Solution:
#undef bool

Try using BOOL instead of Boolean

Related

What do curly braces inside a function's argument list mean in C? [duplicate]

This code:
#include <stdio.h>
int main()
{
void (^a)(void) = ^ void () { printf("test"); } ;
a();
}
Compile without warning with clang -Weverything -pedantic -std=c89 (version clang-800.0.42.1) and print test.
I could not find any information about standard C having lambda, also gcc has it's own syntax for lambda and it would be strange for them do this if a standard solution existed.
This behavior seems to be specfic to newer versions of Clang, and is a language extension called "blocks".
The Wikipedia article on C "blocks" also provides information which supports this claim:
Blocks are a non-standard extension added by Apple Inc. to Clang's implementations of the C, C++, and Objective-C programming languages that uses a lambda expression-like syntax to create closures within these languages. Blocks are supported for programs developed for Mac OS X 10.6+ and iOS 4.0+, although third-party runtimes allow use on Mac OS X 10.5 and iOS 2.2+ and non-Apple systems.
Emphasis above is mine. On Clang's language extension page, under the "Block type" section, it gives a brief overview of what the Block type is:
Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.
GCC also has something similar to blocks called lexically scoped nested functions. However, there are some key differences also note in the Wikipedia articles on C blocks:
Blocks bear a superficial resemblance to GCC's extension of C to support lexically scoped nested functions. However, GCC's nested functions, unlike blocks, must not be called after the containing scope has exited, as that would result in undefined behavior.
GCC-style nested functions also require dynamic creation of executable thunks when taking the address of the nested function. [...].
Emphasis above is mine.
the C standard does not define lambdas at all but the implementations can add extensions.
Gcc also added an extension in order for the programming languages that support lambdas with static scope to be able to convert them easily toward C and compile closures directly.
Here is an example of extension of gcc that implements closures.
#include <stdio.h>
int(*mk_counter(int x))(void)
{
int inside(void) {
return ++x;
}
return inside;
}
int
main() {
int (*counter)(void)=mk_counter(1);
int x;
x=counter();
x=counter();
x=counter();
printf("%d\n", x);
return 0;
}

cmake CheckSymbolExists for intrinsic

I'd like to check for intel intrinsics such as _mm_popcnt_u32 or _mm_blendv_epi8 using cmake. However the function check_symbol_exists doesn't work properly depending on the compiler. (it works with Clang but not with GCC). Indeed it is documented
If the header files declare the symbol as a function or variable then the symbol must also be available for linking (so intrinsics may not be detected).
Is there a simple way to check for those ?
As the CMake documentation also states:
If the symbol is a type, enum value, or intrinsic it will not be
recognized (consider using CheckTypeSize or CheckCSourceCompiles).
So, try to compile a small example with the Intel intrinsic using CheckCSourceCompiles. E.g.:
include(CheckCSourceCompiles)
check_c_source_compiles("
int main() {
int tmp = _mm_popcnt_u32(0);
return 0;
}
"
HAVE_INTRINISC
)

In Objective-C ARC, what are "BPTRs declared within extern "BCPL" blocks"?

In the Clang documentation for ARC, it says:
ARC applies to Objective-C pointer types, block pointer types, and
[beginning Apple 8.0, LLVM 3.8] BPTRs declared within extern "BCPL"
blocks.
What are these "BPTRs declared within extern "BCPL" blocks"?
It's a small in-joke.
C++ has the ability to mark identifiers with C linkage, which usually just means no name mangling of functions with the same name but different parameter signature, since C, until recently, had no concept of overloading1.
The way you specify that linkage is by surrounding the identifiers with:
extern "C" {
whatever ...
}
Now, BCPL is a language that pre-dates even C (it actually forms part of the C lineage) and its "linkage" (for want of a better word) was simply a table of addresses known as the global vector.
The author of that document you reference was simply being humorous, CLang doesn't actually provide extern "BCPL" things. You'll also notice that the current version of LLVM is 3.2 with 3.3 not due until June this year. Another indication that the author was having us on, with the LLVM 3.8 comment.
Since the intent of that sentence was simply to show how annotations (within []) work, the rest of the text was largely irrelevant.
1 With the introduction of type-generic expressions in C11, it now it has overloading of a sort, though done at compile time rather than run time.
This line is obviously taken randomly from an unknown context just to demonstrate revision markers like [beginning Apple 8.0, LLVM 3.8], and BPTRs and BCPL do not mean anything specific. Generally, BPTR means something like byte pointer.

Objective-C and Bison warning: stray `#'

When I generate my parser with bison, I obtain this warning:
warning: stray `#'
But that is because I have some legal Objective-C code containing #, for instance this is one of the rules having the warning:
file : axiom production_rule_list { NSLog(#"file"); }
;
Is there any risk to use # in the code? If not, how to tell bison that it is a legitimate use of #?
Thanks in advance.
The message is just a warning. You can ignore it. If you're using Xcode, it won't even show you the warning in its Issue Navigator.
Rename your Bison input file to have a .ym extension instead of a .y extension. That tells Xcode that it's a grammar with Objective-C actions.
If you want to suppress the warning, you can use a #define AT #.
The code in the braces is just copied, apart from replacing the $… sequences with the code to give the relevant token. This appears to work fine with Objective-C, although if you're using ARC, you might need to do some digging (or just add extra blocks (in the C sense)) to make sure that objects are freed as soon as possible.
As per the documentation in Actions - Bison 2.7, it appears that the code between the curly braces is expected to be C code. As such I doubt that you can use objective-c constructs there.
However you could create an external C function to do the work for you like:
Logit(char* message)
{
NSLog(#"%s",message);
}
And use that in the Bison action
file : axiom production_rule_list { Logit("file"); }
;

How do I flag a function as being deprecated in an iOS Objective-C header file?

How do I flag a function as being deprecated in an iOS Objective-C header file?
I'm guessing there's just some keyword I can stick after the function somewhere?
I would like for a compiler warning to be generated should anyone try and use the deprecated function, similar to the behavior seen in Apple's APIs.
Try appending an attribute to your method declaration:
- (void)fooBar __attribute__ ((deprecated));
Taken from here.
Instead of __attribute__((deprecated)), you can use use the macros defined in <cdefs.h>:
- (void)fooBar __deprecated;
// Or better:
- (void)fooBar __deprecated_msg("Use barFoo instead.");
Or you can use the macros defined in <AvailabilityMacros.h>:
- (void)fooBar DEPRECATED_ATTRIBUTE;
// Or better:
- (void)fooBar DEPRECATED_MSG_ATTRIBUTE("Use barFoo instead.");
If you use Objective-C, it makes no difference as you are going to use a modern compiler, so you can go for Apple short syntax __deprecated_msg(). But if you use C for cross-platform, then DEPRECATED_MSG_ATTRIBUTE() uses the optimal availability definitions (for instance, it supports GCC3.1).
Tim's answer will actually produce a compiler warning; the other versions are merely comments which have no effect w.r.t. the compiler.
If you look at /usr/include/AvailabilityMacros.h, you'll see how Apple does this. That header uses __attribute__((deprecated)) and __attribute__((unavailable)) depending on whether the API is present but deprecated, or has actually been removed from the OS.
From Apple's SFAuthorization.h:
/*!
DEPRECATED: Use obtainWithRight:flags:error:
#method permitWithRight:flags:
#abstract Call permitWithRight to gain a right to have
access to a privilege operation.
#param rightName The name of an authorization right.
#param flags Authorization flags.
*/
- (OSStatus)permitWithRight:(AuthorizationString)rightName
flags:(AuthorizationFlags)flags;
If you're not using an automated documentation builder I'd say something like this is enough:
- (void)doSomething; /* DEPRECATED */
You could also follow the HeaderDoc manual. Where this syntax is used:
/*!
* #abstract Foo is good for bar.
*
* #deprecated in version 2.0
*/