What does one do to make something like this work?
void (^)(void) *someBlock = ^{
//some code
};
Dmitry's answer is exactly right. Think of the block syntax as a C function declaration:
// C function -> <return type> <function name> (<arguments>)
void someFunction(void)
{
// do something
}
// block -> <return type> (^<block variable name>) (<arguments>)
void (^someBlock)(void) = ^{
// do something
};
Another example:
// C function
int sum (int a, int b)
{
return a + b;
}
// block
int (^sum)(int, int) = ^(int a, int b) {
return a + b;
};
So just think of the block syntax as a C function declaration:
First the return type int, then the name of the block variable (^sum) and then the list of arguments types (int, int).
If, however, you need a certain type of block frequently in your app, use a typedef:
typedef int (^MySumBlock)(int, int);
Now you can create variables of the MySumBlock type:
MySumBlock debugSumBlock = ^(int a, int b) {
NSLog(#"Adding %i and %i", a, b);
return a + b;
};
MySumBlock normalSumBlock = ^(int a, int b) {
return a + b;
};
Hope that helps :)
Just block syntax
void (^someBlock)(void) = ^{
//some code
};
Related
I have mocked a function which takes std::set (stl) as an argument and I expected it to be called with the right args. std::set is a set of user-defined struct and I just want to verify one field of that struct to have one value for all the member of the set.
ie
struct my_struct {
int i;
int j;
int k;
}
using my_set = std::set<my_struct>;
MOCK_METHOD(void, my_func, (my_set));
EXPECT_CALL(obj, my_func(_))
.Times(1);
Now I want to expect my_func to be called with my_set and each member of my_set is my_struct and my_struct.i should be 1 for all the members.
I understand it could be done with Matcher and Each but now sure how to do that as I run into compilation error
The key is to use ::testing::Each matcher with ::testing::Field matcher combined. Each iterates over all elements of the container argument and Field matcher allows you to set proper expectations on the user-defined struct fields. Complete example:
struct my_struct {
int i;
int j;
int k;
};
auto my_set_comp = [](const auto& l, const auto& r) { return std::tie(l.i, l.j, l.k) < std::tie(r.i, r.j, r.k); };
using my_set = std::set<my_struct, decltype(my_set_comp)>;
class MockClass {
public:
MOCK_METHOD(void, my_func, (my_set));
};
TEST(SetTest, test1) {
MockClass obj{};
my_set a_set{my_set_comp};
a_set.emplace(my_struct{1, 1, 1});
a_set.emplace(my_struct{1, 2, 2});
a_set.emplace(my_struct{1, 3, 3});
EXPECT_CALL(obj, my_func(::testing::Each(::testing::Field(&my_struct::i, 1)))).Times(1);
obj.my_func(a_set);
}
or here.
I am new to c++/cli, the situation I faced is that:
the project I am doing needs to use an external dll, in my functions I need to use classes A, B and C which are from this dll, I put them in my .h file, the .h file looking like:
#include library I use
public ref class MyClass
{
public:
MyClass();
~MyClass();
otherfuc();
private:
A *a;
B *b;
C *c;
}
My .cpp file looking like:
MyClass::MyClass()
{
a = new A();
b = new B(*a);
c = b->func(); //error happened
}
MyClass::otherfunc()
{
c->func_c()
}
Class A, B, C are unmanaged class, so I only have one way to declare them in managed class, just like I do in the header file. In class B, it has a function which is called func, this function return class type C, I tried c = &b->func(), in this way, it will throw AccessViolationException, if I tried c = b->func, then the error is function call missing argument. What should I do, please help!!!
From what you've written my guess is that B::func() is declared to return a C instance as a temporary:
class B {
public:
C func();
};
Allocate an instance of C as a copy of temporary:
class A {
};
class C {
public:
C(int _i) : i(_i) {}
int func_c() { return i; }
int i;
};
class B {
public:
B(A & a) {}
C func() { return C(5); }
};
public ref class MyClass {
public:
MyClass();
~MyClass();
int otherfunc();
private:
A *a;
B *b;
C *c;
};
MyClass::MyClass()
{
a = new A();
b = new B(*a);
c = new C(b->func());
}
MyClass::~MyClass() {
delete a;
delete b;
delete c;
}
int MyClass::otherfunc()
{
return c->func_c();
}
void f() {
MyClass^ mc = gcnew MyClass();
int i = mc->otherfunc();
}
This assumes C is copyable (or moveable) and that copying it make sense for what you are doing.
When I check out the src of Underscore project, then I found that the block somehow comprehensive for me:
typedef BOOL (^UnderscoreTestBlock)(id obj);
In the class, it define this class method:
+ (UnderscoreTestBlock (^)(UnderscoreTestBlock))negate
{
return ^UnderscoreTestBlock (UnderscoreTestBlock test) {
return ^BOOL (id obj) {
return !test(obj);
};
};
}
and how can I understand these code, Thanks!
I think that you got it right. negate is a class method which returns a block.
That returned block takes an UnderscoreTestBlock argument and returns another UnderscoreTestBlock. Example:
UnderscoreTestBlock isANumber = ^BOOL (id obj) {
return [obj isKindOfClass:[NSNumber class]];
};
BOOL b1 = isANumber(#123); // YES
BOOL b2 = isANumber(#"abc"); // NO
UnderscoreTestBlock isNotANumber = [Underscore negate](isANumber);
BOOL b3 = isNotANumber(#123); // NO
BOOL b4 = isNotANumber(#"abc"); // YES
[Underscore negate] returns a block that is called with the isANumber argument.
The return value of that call is the block
^BOOL (id obj) { return !test(obj); };
where test is the isANumber argument, which is captured by the block.
I am sure that there are good reasons why the Underscore project defines the negate
method like this, it is probably necessary for their "functional" notation.
Otherwise a slightly simpler way would be to define a method
+ (UnderscoreTestBlock)negateBlock:(UnderscoreTestBlock)test
{
return ^BOOL (id obj) {
return !test(obj);
};
}
which would be used like
UnderscoreTestBlock isNotANumber = [Underscore negateBlock:isANumber];
I'm looking for an annotation something like
-(SomeStruct *) structFromInternals __attribute__((returns_malloced_ptr))
{
SomeStruct *ret = malloc(sizeof(SomeStruct));
//do stuff
return ret;
}
to soothe the clang static analyzer beasts.
The only viable attributes link I can find is for GCC, but it doesn't even include ns_returns_retained, which is in an extension, I assume.
EDIT:
as to why this is needed, I have a scenario that I can't repro in a simple case, so it may have to do with a c lib in an Objective-C project... The gist is, I get a static analyzer warning that the malloc in createStruct is leaked:
typedef struct{
void * data;
size_t len;
}MyStruct;
void destroyStruct(MyStruct * s)
{
if (s && s->data) {
free(s->data);
}
if (s) {
free(s);
}
}
MyStruct * createStructNoCopy(size_t len, void * data)
{
MyStruct * retStruct = malloc(sizeof(MyStruct));
retStruct->len = len;
retStruct->data = data;
return retStruct;
}
MyStruct * createStruct(size_t len, void * data)
{
char * tmpData = malloc(len);
memcpy(tmpData, data, len);
return createStructNoCopy(len, tmpData);
}
MyStruct * copyStruct(MyStruct * s)
{
return createStruct(s->len, s->data);
}
The function annotation ownership_returns(malloc) will tell the Clang static analyser that the function returns a pointer that should be passed to free() at some point (or a function with ownership_takes(malloc, ...)). For example:
void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
void __attribute((ownership_takes(malloc, 1))) my_free(void *);
...
void af1() {
int *p = my_malloc(1);
return; // expected-warning{{Potential leak of memory pointed to by}}
}
void af2() {
int *p = my_malloc(1);
my_free(p);
return; // no-warning
}
(See the malloc-annotations.c test file for some more examples of their use.)
At the moment, these annotations only take effect when the alpha.unix.MallocWithAnnotations checker is run (which is not run by default). If you're using Xcode, you'll need to add -Xclang -analyzer-checker=alpha.unix.MallocWithAnnotations to your build flags.
I'm having trouble writing a nested block. Say I want a block that takes and integer. That block returns a block that takes another integer, and returns the sum of the two integers. I haven't had any luck writing this out. Here's one try, which is no worse than any other of mine:
(int ^(int)) (^bblock)(int) = ^(int a) {
return ^(int b){ return a + b; };
};
Can anybody spot what's wrong?
Quite ugly, but you can do it using parenthesis instead of typedefs:
int (^(^functor)(int))(int) = ^(int a) {
return Block_copy(^(int b) {
return a + b;
});
};