What is the required syntax to pass a block to a pure C function? - objective-c

I have a pure C function, to which I would like to pass a block (a closure?). As per Apple, the block should always be the last parameter to a function.
double pureCfunctionWithABlockParameter( int ignore, double ignore2, void (^myVoidBlockWithoutParameters)(void) ) {
myVoidBlockWithoutParameters(); /
return 0.0;
}
Next is the Objective C code to call the C function:
- (void) testBlockFunctionality {
declare and define the block:
void (^myBlock1)(void) ;
myBlock1=^(void){ NSLog(#"myBlock1 just logs this message to the console");};
Attempt to invoke the block directly, without parentheses. This doesn't work. Xcode warns result is unused. Block's message is NOT logged to console.
myBlock1;
Now attempt to invoke the block directly, this time with parentheses. This works as intended. No Xcode warnings, and the block's message IS logged to console.
myBlock1();
Now call the function, passing the block as parameter, WITHOUT parentheses. This works as intended, but the syntax is not consistent with the previous invocation of the block.
double someNumber;
someNumber= pureCfunctionWithABlockParameter(0, 1, myBlock1 );
Now call the function, again passing the block as a parameter, this time WITH parentheses. This doesn't work, it won't even compile, as Xcode gives a: "Passing 'void' to parameter of incompatible type 'void (^)(void)'" message.
someNumber= pureCfunctionWithABlockParameter(0, 1, myBlock1());
At the end of it all, I am actually looking to have a block defined that gets passed an int parameter, like this:
void(^block)(int)
But I cannot progress to that because of what I think is a syntax issue.
I've looked in Apple's Block Programming Topics, and even K&R C, but no luck.

The question has caused some confusion, because blocks (in the question's sense) are not a feature of standard C. Apple added them as an extension to its C and C++ compilers when it added them to Objective C, but they are not a C thing outside the Apple ecosystem. I confess that I've no experience actually using them, but as far as I can tell from the docs, such as these, the syntax was chosen so as to be the same for C, C++, and Objective C. Indeed, some sources claim that details of the syntax were chosen specifically to avoid the possibility of conflict with C++.
From a C perspective, accepting a block as a parameter and calling a block received that way are thoroughly analogous to accepting a function pointer and calling the pointed-to function, respectively. Your example C function appears to be correct.
Similar applies to declaring and and working with blocks, in all three languages -- it is analogous to declaring and working with function pointers. I am confident that this was an intentional design consideration. Thus
void (^myBlock1)(void) ;
indeed declares myBlock1 as a block taking no parameters and returning nothing, but does not define its value. Having elsewhere set a valid value for it, such as is demonstrated in the question, the OP observes
Attempt to invoke the block directly, without parentheses. This
doesn't work. Xcode warns result is unused. Block's message is NOT
logged to console.
myBlock1;
, as indeed should be expected. That's a statement expression evaluating to the value of the block, not to the result of executing the block. It is analogous to
int myInt = 1;
myInt; // specifically, analogous to this
To execute a block, one provides a postfix argument list in parentheses (even if the list is empty), just like when calling a function through a function pointer:
Now attempt to invoke the block directly, this time with parentheses.
This works as intended. No Xcode warnings, and the block's message IS
logged to console.
myBlock1();
The presence or absence of an argument list is what disambiguates whether one is accessing the block's value or calling it.
The confusion is about passing a block to a function (or method):
Now call the function, passing the block as parameter, WITHOUT
parentheses. This works as intended, but the syntax is not consistent
with the previous invocation of the block.
double someNumber;
someNumber= pureCfunctionWithABlockParameter(0, 1, myBlock1 );
Yet, contrary to the assertion in the question, that syntax as completely consistent, both internally consistent with other aspects of block syntax and usage, and consistent with analogous function pointer syntax and usage. That passes the block to the function, identifying the block by its name. The block itself is passed, not the result of executing it, because no argument list for it is provided.
At the end of it all, I am actually looking to have a block defined
that gets passed an int parameter, like this:
void (^block)(int)
But I cannot progress to that because of what I think is a syntax
issue.
A C function accepting and using such a block might look like this
void pass_2(void (^do_something)(int)) {
do_something(2);
}
Given variable block declared as shown above, and assigned a valid block as its value, that function could be called like so:
pass_2(block);
Just as we recognize that function pass_2 is called by the presence of an argument list, we recognize that the value of variable block is passed as an argument -- not called -- by the absence of an argument list.

Related

Kotlin construction: function call with additional body - what such construction means or how it is called (if I want to look it up in the docs)?

I am seeing the Kotlin code:
navController.navigate("sales_order/" + it.toString()) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
which I can describe as "function call" (navController.navigate) "with additional body" ({...}). How such construction is called (if I want to look it up in the docs) and what does it mean?
When I checked the type of navController.navigate(...) args, then there are 2 arguments. The first argument - string - is provided in () and I am trying to guess, that everything inside {...} is the content for the second argument which has type NavOptionsBuilder in this case. So, I can guess that NavOptionsBuilder has 3 arguments: 1 function call popUpTo that returns some object and 2 named arguments (launchSingleTop, restoreState) which are Boolean type.
Am I deciphering this construction right - just another way of passing arguments - or is there something deeper?
Am I deciphering this construction right
Almost. You got the beginning right, but the end is not exactly correct.
Let's start with what you got right, and throw in some vocabulary here for posterity. Indeed, you seem to be using the overload of navigate that takes 2 arguments: a string route and a builder function.
Functions in kotlin can be passed in multiple ways, but the most common (and the one used here) is passing a lambda expression. Because the syntax for lambda expressions is based on braces ({ ... }), it makes it look like blocks of code, so the Kotlin language went one step further and allowed to pass lambda expressions outside of the parentheses of the function call when the lambda is the last argument. The reason for this is exactly to allow this kind of constructions which look like their own configuration language. This is what is usually referred to as DSLs (Domain Specific Languages).
Now about what you got wrong:
So, I can guess that NavOptionsBuilder has 3 arguments
Not really. NavOptionsBuilder is the receiver of the function that is passed as the second argument of navigate. This means that, within the lambda that you pass, a NavOptionsBuilder instance is implicitly available as this.
This, in turn, means that you can access methods and properties of NavOptionsBuilder within that lambda block. This is what popUpTo, launchSingleTop, and restoreState are: methods and properties of NavOptionsBuilder - not "arguments".
You can find more general info about this here.

Fortran Functions with a pointer result in a normal assignment

After some discussion on the question found here Correct execution of Final routine in Fortran
I thought it will be useful to know when a function with a pointer result is appropriate to use with a normal or a pointer assignment. For example, given this simple function
function pointer_result(this)
implicit none
type(test_type),intent(in) pointer :: this
type(test_type), pointer :: pointer_result
allocate(pointer_result)
end function
I would normally do test=>pointer_result(test), where test has been declared with the pointer attribute. While the normal assignment test=pointer_result(test) is legal it means something different.
What does the normal assignment imply compared to the pointer assignment?
When does it make sense to use one or the other assignment?
A normal assignment
test = pointer_result()
means that the value of the current target of test will be overwritten by the value pointed to by the resulting pointer. If test points to some invalid address (is undefined or null) the program will crash or produce undefined results. The anonymous target allocated by the function will have no pointer to it any more and the memory will be leaked.
There is hardly any legitimate use for this, but it is likely to happen when one makes a typo and writes = instead of =>. It is a very easy one to make and several style guides recommend to never use pointer functions.

Dynamic casting in SV using $cast function and task

How can we tell if the calling of $cast is of a function or of a task. How would calling of each differ? One thing I understand is that with the function call, I'll be able to use assert(). But other than that, what tells us if the call is of the $cast function or the $cast task? In either case, we'd be doing something like $cast(pkt, pkt1);
LRM gives the syntax of the $cast function as
function int $cast( singular dest_var, singular source_exp );
and of the $cast task as
task $cast( singular dest_var, singular source_exp );
and goes on to explain that
Use of $cast as either a task or a function determines how invalid assignments are handled.
When called as a task, $cast attempts to assign the source expression
to the destination variable. If the assignment is invalid, a run-time
error occurs, and the destination variable is left unchanged.
When called as a function, $cast attempts to assign the source expression
to the destination variable and returns 1 if the cast is legal. If the
cast fails, the function does not make the assignment and returns 0.
When called as a function, no run-time error occurs, and the
destination variable is left unchanged.
Please explain.
Your comment is correct: if $cast is used as part of an expression, it is considered called as a function. That wording is derived from Verilog terminology when functions could only be used in an expression and never could exist as a simple statement like a task call. But once SystemVerilog added functions with void return types, that wording does not fit as well anymore.

When isn't inlining safe?

I keep reading (for example in the Closure Compiler and other compilers) that inlining of functions isn't always safe. Could you please provide an example when inlining of functions shouldn't be done?
In many languages, inlining a function will have no observable semantic effects, although it is likely to affect the compiled size and execution time of the program. However, that is not true in languages in which the call stack and/or local variable bindings are visible.
As a simple example, in Javscript the local variable arguments always refers to an array-like object containing the arguments to the current function call. Clearly, if the function in which it occurred were inlined, its semantics would change. An inliner would have to either refuse to inline a function whose body references arguments or it would have to modify the code in a way which preserved the semantics, possibly by creating another local variable with a different name and substituting the reference.
Another example would be the (non-recommended) use of eval. Name lookup in the string passed to eval is done within the scope of the function which calls eval. For example:
inner = function(s) { var x = 4; return eval(s); }
outer = function(s) { var x = 3; return inner(s); }
outer("x+1")
Here the value returned by outer is 5. If inner were inlined, which would require renaming its local variable x to avoid name conflict, the value returned would be 4. (If both inner and outer were inlined, the value would probably be something else again.)
In general, it's going to be very difficult to inline a function which calls eval because there is no easy way to know the contents of the argument to eval.

Enforcing to supply a completion block

I'm wondering about whether or not this is good practice:
I have a method that takes in parameters and a callback block, let's say something along the lines of:
-(void)loginWithUsername:(NSString *)username andPassword:(NSString *)password withCompletion:(LoginManagerCompletionBlock)completionHandler;
Now in this specific case, there is no use in calling this method without a completion handler, as it triggers a redundant call to a login web service (also, it does not change the state of anything - not client side nor server side). I would like to avoid these situations by actively enforcing the requirement of passing me a completion block in order to make this web service call. I sort of think of this as a "#required" method in an Objective C protocol. So my questions are:
Is requiring a completion block in order to perform an action good practice in Objective C?
(Edit: Answered) How do I enforce this requirement? Is there built-in language syntax that can help me out here?
Thanks
You can use the function attribute nonnull(params), where params is 1 or more comma-separated parameter numbers, to indicate that a parameter should not be null (nonnull without parentheses means all pointer parameters should not be null). For your example:
- (void) loginWithUsername:(NSString *)username
andPassword:(NSString *)password
withCompletion:(LoginManagerCompletionBlock)completionHandler
__attribute__((nonnull(3)));
However, while this is a compile time check and produces a warning it will only do so if null is passed directly. If the argument value is an expression which evaluates to null, e.g. a variable with a null value, then this will not be caught.
If a parameter being null is an error you can add a runtime check within the method itself using NSParameterAssert(parameter), where parameter is the name of one of the method's parameters, to check for this condition. This call is defined to print an error message and throw an exception if its argument evaluates to false, and null evaluates to false.
This is exactly what NSParameterAssert is for. Use it to check that parameters aren't nil.
NSParameterAssert( completionParameter );
Though, in this specific case, it's probably best to log the completion handler being nil and return. There is no point doing any additional work. You probably want the assertion during development to make it obvious that you have an issue that needs to be resolved.