Trouble with block, iOS - objective-c-blocks

I get this error when trying to define and assign a block:
int (^bl)(int) = ^(int k)
{
[_self c2:k]; // incompatible block pointer types initializing 'int (^)(int)' with an expression of type 'void (^)(int)'
};
This is from a blocks tutorial:
What is going on?

Change the return type of bl from int to void.
void (^bl)(int) = ^(int k) {
[_self c2:k];
};
If you look at the language specification for blocks you will see what's going on:
The return type is optional and is inferred from the return statements. If the return statements return a value, they all must return a value of the same type. If there is no value returned the inferred type of the Block is void; otherwise it is the type of the return statement value.
In Apples example case the return type will be the type of num * multiplier which is int matching the return type of the block variable myBlock.
But in your case there is no return statements so the return type will be void which does not match the return type of the block variable bl.

Related

Why can't clang++ deduce this lambda's return value?

Consider the following function:
#include <utility>
#include <iterator>
#include <algorithm>
template<template<class, class> class Map, typename Key, typename Value , typename F>
auto transform_values(const Map<Key,Value>& map, const F& value_mapper)
{
using mapped_value_type = decltype(value_mapper(std::declval<Value>()));
Map<Key, mapped_value_type> transformed;
std::transform(map.cbegin(), map.cend(), std::inserter(transformed, transformed.begin()),
[&value_mapper](const auto& pair) {
const auto& key = pair.first;
const auto& value = pair.second;
return {key, value_mapper(value)};
}
);
return transformed;
}
g++ 12 accepts this, clang++ 14 does not (GodBolt). clang++ 14 says:
<source>:15:20: error: cannot deduce lambda return type from initializer list
return {key, value_mapper(value)};
^~~~~~~~~~~~~~~~~~~~~~~~~~
Why won't it deduce the lambda's type?
I can't see how the compiler can deduce return type here. The return type of the lambda should be convertible to the type pointed to by the output iterator, but without complete container class it doesn't even know what this type is.
Edit.
For the part what rule makes it fail (i.e. why no valid specialization can be generated), i believe it refers to 9.2.9.6.2 Placeholder type deduction / 2.1.2 rule:
A type T containing a placeholder type, and a corresponding initializer-
clause E, are determined as follows:
For a non-discarded return statement that occurs in a function declared with a return type that contains a placeholder type, T is the declared return type.
...
If the operand is a braced-init-list ([dcl.init.list]), the program is ill-formed.

Using method_getReturnType to call specific types of instance member functions

I'm new to Objective-C so I don't have much idea about the language.
What I'm trying to do is go through all available instance methods of an object and call the ones that take no arguments, return bool and start with the string "func".
Here's how I get the methods:
uint32_t methodCount = 0;
Method * methods = class_copyMethodList(object_getClass(self), &methodCount);
I iterate through the methods and when the above condition matches, try to call them:
NSString * methodName = [NSString stringWithUTF8String:sel_getName(method_getName(method))];
char retTyp[10];
method_getReturnType(method, retTyp, 10);
const char * desiredRetType = "B";
if([methodName hasPrefix:#"func"] &&
(0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
(2 == method_getNumberOfArguments(method)))
{
bool * (* testMethod) (id, Method) = (void (*) (id, Method, ...)) method_invoke;
result = testMethod(self, method);
}
I had to experimentally figure out what the return type string is (turns out it's "B" for bool), and the number of arguments.
I'm getting the following error on the line where I'm trying to call the function using method_invoke:
cannot initialize a variable of type 'bool *(*)(__strong id, Method)' (aka 'bool *(*)(__strong id, objc_method *)') with an rvalue of type 'void (*)(__strong id, Method, ...)' (aka 'void (*)(__strong id, objc_method *, ...)'): different return type ('bool *' vs 'void')
Is there a better way to way to do this than class_copyMethodList?
How do I cast the function correctly so as to not get an error?
Is it possible that the method_getReturnType() conversion of return
types may change from system to system? Or is it always B for bool?
NVM, I figured it out. Instead of using method_invoke on the method name, I did this:
NSString * methodName = [NSString stringWithUTF8String:sel_getName(method_getName(method))];
char retTyp[10];
method_getReturnType(method, retTyp, 10);
const char * desiredRetType = "B";
if([methodName hasPrefix:#"func"] &&
(0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
(2 == method_getNumberOfArguments(method)))
{
SEL testMethod = method_getName(method);
return [self performSelector:testMethod];
}

How to declare a C function with an undetermined return type?

Can I declare a C function with an undetermined return type (without C compiler warning)? The return type could be int, float, double, void *, etc.
undetermined_return_type miscellaneousFunction(undetermined_return_type inputValue);
And you can use this function in other functions to return a value (although that could be a run time error):
BOOL isHappy(int feel){
return miscellaneousFunction(feel);
};
float percentage(float sales){
return miscellaneousFunction(sales);
};
What I'm looking for:
To declare and to implement a C function (or Obj-C method) with an undefined-return-type could be useful for aspect-oriented programming.
If I could intercept Obj-C messages in another function in run time, I might return the value of that message to the original receiver or not with doing something else action. For example:
- (unknown_return_type) interceptMessage:(unknown_return_type retValOfMessage){
// I may print the value here
// No idea how to print the retValOfMessage (I mark the code with %???)
print ("The message has been intercepted, and the return value of the message is %???", retValOfMessage);
// Or do something you want (e.g. lock/unlock, database open/close, and so on).
// And you might modify the retValOfMessage before returning.
return retValOfMessage;
}
So I can intercept the original message with a little addition:
// Original Method
- (int) isHappy{
return [self calculateHowHappyNow];
}
// With Interception
- (int) isHappy{
// This would print the information on the console.
return [self interceptMessage:[self calculateHowHappyNow]];
}
You can use a void * type.
Then for example:
float percentage(float sales){
return *(float *) miscellaneousFunction(sales);
}
Be sure not to return a pointer to a object with automatic storage duration.
You may use the preprocessor.
#include <stdio.h>
#define FUNC(return_type, name, arg) \
return_type name(return_type arg) \
{ \
return miscellaneousFunction(arg); \
}
FUNC(float, undefined_return_func, arg)
int main(int argc, char *argv[])
{
printf("\n %f \n", undefined_return_func(3.14159));
return 0;
}
May be a union as suggested by thejh
typedef struct
{
enum {
INT,
FLOAT,
DOUBLE
} ret_type;
union
{
double d;
float f;
int i;
} ret_val;
} any_type;
any_type miscellaneousFunction(any_type inputValue) {/*return inputValue;*/}
any_type isHappy(any_type feel){
return miscellaneousFunction(feel);
}
any_type percentage(any_type sales){
return miscellaneousFunction(sales);
}
Here with ret_type you can know data type of return value and ret_type. i,f,d can give you corresponding value.
All elements will use same memory space and only one should be accessed.
Straight C doesn't support dynamically-typed variables (variants) since it is statically typed, but there might be some libraries that do what you want.

Why can't I overload a function by its return type? [duplicate]

This question already has answers here:
Function overloading by return type?
(14 answers)
Closed 9 years ago.
Why can't function is not overloaded by its return types, There should no language which support such overloading. I want to know the reason that what was happening if its allow, or why its not allowing such function overloading by its return type.
int func();
bool func();
int main()
{
int iret = func();
bool bret = func();
}
Always arise this quetion in my mind. Hoping satisfied answer.
A function like
double function fn1()
{
int a = 2;
return a;
}
In the above e.g. a will be implicitly converted to double when returned.
int function fn1()
{
double a = 2;
return a;
}
In the above e.g. a will be implicitly converted to int when returned.
A fn call for this fn would be like int a = fn1(); or double a = fn1();.
In either case both definitions can cause ambiguity as to which is to be called.
The fact that the returned values are stored in int or double doesn't make a difference in determining the fn to be called. The function is first resolved and then executed and then the return value is assigned.
If both didn't have a return type the call would be simply fn1(); making it ambiguous, whether to call fn1() with return type int or double

Structure of a block declaration

When declaring a block what's the rationale behind using this syntax (i.e. surrounding brackets and caret on the left)?
(^myBlock)
For example:
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
C BLOCKS: Syntax and Usage
Variables pointing to blocks take on the exact same syntax as variables pointing to functions, except * is substituted for ^. For example, this is a function pointer to a function taking an int and returning a float:
float (*myfuncptr)(int);
and this is a block pointer to a block taking an int and returning a float:
float (^myblockptr)(int);
As with function pointers, you'll likely want to typedef those types, as it can get relatively hairy otherwise. For example, a pointer to a block returning a block taking a block would be something like void (^(^myblockptr)(void (^)()))();, which is nigh impossible to read. A simple typedef later, and it's much simpler:
typedef void (^Block)();
Block (^myblockptr)(Block);
Declaring blocks themselves is where we get into the unknown, as it doesn't really look like C, although they resemble function declarations. Let's start with the basics:
myvar1 = ^ returntype (type arg1, type arg2, and so on) {
block contents;
like in a function;
return returnvalue;
};
This defines a block literal (from after = to and including }), explicitly mentions its return type, an argument list, the block body, a return statement, and assigns this literal to the variable myvar1.
A literal is a value that can be built at compile-time. An integer literal (The 3 in int a = 3;) and a string literal (The "foobar" in const char *b = "foobar";) are other examples of literals. The fact that a block declaration is a literal is important later when we get into memory management.
Finding a return statement in a block like this is vexing to some. Does it return from the enclosing function, you may ask? No, it returns a value that can be used by the caller of the block. See 'Calling blocks'. Note: If the block has multiple return statements, they must return the same type.
Finally, some parts of a block declaration are optional. These are:
The argument list. If the block takes no arguments, the argument list can be skipped entirely.
Examples:
myblock1 = ^ int (void) { return 3; }; // may be written as:
myblock2 = ^ int { return 3; }
The return type. If the block has no return statement, void is assumed. If the block has a return statement, the return type is inferred from it. This means you can almost always just skip the return type from the declaration, except in cases where it might be ambiguous.
Examples:
myblock3 = ^ void { printf("Hello.\n"); }; // may be written as:
myblock4 = ^ { printf("Hello.\n"); };
// Both succeed ONLY if myblock5 and myblock6 are of type int(^)(void)
myblock5 = ^ int { return 3; }; // can be written as:
myblock6 = ^ { return 3; };
source: http://thirdcog.eu/pwcblocks/
I think the rationale is that it looks like a function pointer:
void (*foo)(int);
Which should be familiar to any C programmer.