Is this the right way for a block inside a struct to access a member variable in the same struct? - objective-c

I'm experimenting with Obj-C blocks and trying to have a struct with two blocks in it where one block is to change what the other block does.
this is a really roundabout way to do something simple... and there may be better ways to do it, but the point of the exercise is for me to understand blocks. here's the code , it doesn't work, so what am I missing/not understanding and/or doing wrong?
//enumerate my math operation options so i can have something more understandable
//than 0, 1, 2, etc... also makes it easier to add operations, as opTypeTotal
//will be 1 plus the index of the operation before it.
typedef enum
{
opTypeAdd = 0,
opTypeSubtract = 1,
opTypeTotal
} opType;
//not sure if (struct someMathStruct)* is correct, probably is wrong
//the intent is to pass a pointer to someMathStruct, but the compiler
//won't know about its existance until a few lines later...
typedef (void)(^changeBlock)(opType,(struct someMathStruct)*);
typedef (void)(^mathBlock)(int,int,int*);
//hold two blocks, to be defined later at runtime
typedef struct someMathStruct{
mathBlock doMath;
changeBlock changeOperation;
} SomeMath;
//i want to declare an array of blocks of type mathBlock
//the intent is to have the array index to correspond with the opTypes enumerated above
//almost certain i'm doing this wrong
mathBlock *m[opTypeTotal] = malloc(sizeof(mathBlock *)*opTypeTotal);
//just two simple math operations as blocks
m[opTypeAdd] = ^(void)(int a,int b,int *result){*result = a+b;};
m[opTypeSubtract] = ^(void)(int a,int b,int *result){*result = a-b;};
//this block is what's supposed to change the other block in the struct
//it takes an opType, and a pointer to the SomeMath struct
//is this the right way to access the member variables of the struct?
changeBlock changeMe = ^(void)(opType a, SomeMath *b) {
//should make adding operations as easy as just adding cases
switch (a)
{
case opTypeAdd: *b.doMath=m[a]; break;
case opTypeSubtract:
default: *b.doMath=m[a]; //catch-all goes to subtracting
}
}
...
SomeMath mathFun;
int theTotal = 0; //a test int to work with
//do i need to copy the changeMe block?
//or can i just do what i'm doing here as the block itself isn't unique
mathFun.changeOperation = changeMe;
mathFun->changeOperation(opTypeAdd, &mathFun);
mathFun->doMath(theTotal,11,&theTotal); //result should be 11
mathFun->changeOperation(opTypeSubtract, &mathFun);
mathFun->doMath(theTotal,3,&theTotal); //result should be 8
NSLog(#"the result: %d",theTotal); //should output "the result: 8"

The code seems to work as you expect (the result is 8) once you fix the compilation errors:
Compile with: gcc -o test test.m -framework Foundation
#import <Foundation/Foundation.h>
//enumerate my math operation options so i can have something more understandable
//than 0, 1, 2, etc... also makes it easier to add operations, as opTypeTotal
//will be 1 plus the index of the operation before it.
typedef enum
{
opTypeAdd = 0,
opTypeSubtract = 1,
opTypeTotal
} opType;
struct someMathStruct; // Forward declare this as a type so we can use it in the
// changeBlock typedef
typedef void (^changeBlock) (opType,struct someMathStruct*);
typedef void (^mathBlock) (int,int,int*);
//hold two blocks, to be defined later at runtime
typedef struct someMathStruct{
mathBlock doMath;
changeBlock changeOperation;
} SomeMath;
int main()
{
//i want to declare an array of blocks of type mathBlock
//the intent is to have the array index to correspond with the opTypes
// enumerated above
mathBlock *m = calloc(opTypeTotal, sizeof(mathBlock *));
//just two simple math operations as blocks
m[opTypeAdd] = ^(int a,int b,int *result){*result = a+b;};
m[opTypeSubtract] = ^(int a,int b,int *result){*result = a-b;};
changeBlock changeMe = ^(opType a, SomeMath *b) {
//should make adding operations as easy as just adding cases
switch (a)
{
case opTypeAdd: b->doMath = m[a]; break;
case opTypeSubtract:
default: b->doMath = m[a]; //catch-all goes to subtracting
}
};
SomeMath mathFun;
int theTotal = 0; //a test int to work with
mathFun.changeOperation = changeMe;
mathFun.changeOperation(opTypeAdd, &mathFun);
mathFun.doMath(theTotal,11,&theTotal); //result should be 11
mathFun.changeOperation(opTypeSubtract, &mathFun);
mathFun.doMath(theTotal,3,&theTotal); //result should be 8
NSLog(#"the result: %d",theTotal); //should output "the result: 8"
}

Related

Determine types from a variadic function's arguments in C

I'd like a step by step explanation on how to parse the arguments of a variadic function
so that when calling va_arg(ap, TYPE); I pass the correct data TYPE of the argument being passed.
Currently I'm trying to code printf.
I am only looking for an explanation preferably with simple examples but not the solution to printf since I want to solve it myself.
Here are three examples which look like what I am looking for:
https://stackoverflow.com/a/1689228/3206885
https://stackoverflow.com/a/5551632/3206885
https://stackoverflow.com/a/1722238/3206885
I know the basics of what typedef, struct, enum and union do but can't figure out some practical application cases like the examples in the links.
What do they really mean? I can't wrap my brain around how they work.
How can I pass the data type from a union to va_arg like in the links examples? How does it match?
with a modifier like %d, %i ... or the data type of a parameter?
Here's what I've got so far:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "my.h"
typedef struct s_flist
{
char c;
(*f)();
} t_flist;
int my_printf(char *format, ...)
{
va_list ap;
int i;
int j;
int result;
int arg_count;
char *cur_arg = format;
char *types;
t_flist flist[] =
{
{ 's', &my_putstr },
{ 'i', &my_put_nbr },
{ 'd', &my_put_nbr }
};
i = 0;
result = 0;
types = (char*)malloc( sizeof(*format) * (my_strlen(format) / 2 + 1) );
fparser(types, format);
arg_count = my_strlen(types);
while (format[i])
{
if (format[i] == '%' && format[i + 1])
{
i++;
if (format[i] == '%')
result += my_putchar(format[i]);
else
{
j = 0;
va_start(ap, format);
while (flist[j].c)
{
if (format[i] == flist[j].c)
result += flist[i].f(va_arg(ap, flist[i].DATA_TYPE??));
j++;
}
}
}
result += my_putchar(format[i]);
i++;
}
va_end(ap);
return (result);
}
char *fparser(char *types, char *str)
{
int i;
int j;
i = 0;
j = 0;
while (str[i])
{
if (str[i] == '%' && str[i + 1] &&
str[i + 1] != '%' && str[i + 1] != ' ')
{
i++;
types[j] = str[i];
j++;
}
i++;
}
types[j] = '\0';
return (types);
}
You can't get actual type information from va_list. You can get what you're looking for from format. What it seems you're not expecting is: none of the arguments know what the actual types are, but format represents the caller's idea of what the types should be. (Perhaps a further hint: what would the actual printf do if a caller gave it format specifiers that didn't match the varargs passed in? Would it notice?)
Your code would have to parse the format string for "%" format specifiers, and use those specifiers to branch into reading the va_list with specific hardcoded types. For example, (pseudocode) if (fspec was "%s") { char* str = va_arg(ap, char*); print out str; }. Not giving more detail because you explicitly said you didn't want a complete solution.
You will never have a type as a piece of runtime data that you can pass to va_arg as a value. The second argument to va_arg must be a literal, hardcoded specification referring to a known type at compile time. (Note that va_arg is a macro that gets expanded at compile time, not a function that gets executed at runtime - you couldn't have a function taking a type as an argument.)
A couple of your links suggest keeping track of types via an enum, but this is only for the benefit of your own code being able to branch based on that information; it is still not something that can be passed to va_arg. You have to have separate pieces of code saying literally va_arg(ap, int) and va_arg(ap, char*) so there's no way to avoid a switch or a chain of ifs.
The solution you want to make, using the unions and structs, would start from something like this:
typedef union {
int i;
char *s;
} PRINTABLE_THING;
int print_integer(PRINTABLE_THING pt) {
// format and print pt.i
}
int print_string(PRINTABLE_THING pt) {
// format and print pt.s
}
The two specialized functions would work fine on their own by taking explicit int or char* params; the reason we make the union is to enable the functions to formally take the same type of parameter, so that they have the same signature, so that we can define a single type that means pointer to that kind of function:
typedef int (*print_printable_thing)(PRINTABLE_THING);
Now your code can have an array of function pointers of type print_printable_thing, or an array of structs that have print_printable_thing as one of the structs' fields:
typedef struct {
char format_char;
print_printable_thing printing_function;
} FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING;
FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING formatters[] = {
{ 'd', print_integer },
{ 's', print_string }
};
int formatter_count = sizeof(formatters) / sizeof(FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING);
(Yes, the names are all intentionally super verbose. You'd probably want shorter ones in the real program, or even anonymous types where appropriate.)
Now you can use that array to select the correct formatter at runtime:
for (int i = 0; i < formatter_count; i++)
if (current_format_char == formatters[i].format_char)
result += formatters[i].printing_function(current_printable_thing);
But the process of getting the correct thing into current_printable_thing is still going to involve branching to get to a va_arg(ap, ...) with the correct hardcoded type. Once you've written it, you may find yourself deciding that you didn't actually need the union nor the array of structs.

return of a local variable by ref works

Take a look at this C++ code:
#include <iostream>
using namespace std;
class B{
public:
int& f() {
int local_n = 447;
return local_n ;
} // local_n gets out of scope here
};
int main()
{
B b;
int n = b.f(); // and now n = 447
}
I don't understand why n = 447 at the end of main, because I tried to return a reference to a local_n, when it should be NULL;
Returning a reference to a local variable invokes undefined behavior - meaning you might get lucky and it might work... sometimes... or it might format your hard drive or summon nasal demons. In this case, the compiler generated code that managed to copy the old value off the stack before it got overwritten with something else. Oh, and references do not have a corresponding NULL value...
Edit - here's an example where returning a reference is a bad thing. In your example above, since you copy the value out of the reference immediately before calling anything else, it's quite possible (but far from guaranteed) that it might work most of the time. However, if you bind another reference to the returned reference, things won't look so good:
extern void call_some_other_functions();
extern void lucky();
extern void oops();
int& foo()
{ int bar = 0;
return bar;
}
main()
{ int& x = foo();
x = 5;
call_some_other_functions();
if (x == 5)
lucky();
else
oops();
}

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.

Large number of bitwise enums

I've got a question regarding bitwise enums that I just can't seem to resolve. I've got a number of flags that are represented by a bitwise enum as in the following example:
enum
{
EnumNone=0,
EnumOne = 1<<0,
EnumTwo = 1<<1,
EnumThree = 1<<2,
EnumFour = 1<<3
};
typedef NSUInteger MyEnum;
All is fine with the above example. Based on my research and various helpful posts in stackoverflow (this for example), I've concluded that, using the above example, I'm essentially given 32 options (or shifts if you will), each option representing 1 bit in a 32-bit series of options, which basically tells me that I can go all the way to EnumThirtyTwo = 1 << 31.
My question is this:
Suppose I've more than 32, say 75 flags for example, to represent using a bitwise enum. How would that best be represented?
enum
{
EnumNone=0,
EnumOne = 1<<0,
EnumTwo = 1<<1,
EnumThree = 1<<2,
EnumFour = 1<<3,
...
...
EnumSeventyFive = 1<<75
};
typedef NSUInteger MyEnum;
Would it be a simple matter of changing the declaration of my enum type, say, to: typedef long int MyEnum; or typedef long MyEnum?
You can use a few simple macros/functions and a struct containing a char array of sufficient size - gives you call-by-value semantics, i.e. just like real enums. E.g. something along the lines of (typed directly into answer):
typedef struct
{
char bits[10]; // enough for 80 bits...
} SeventyFiveFlags;
typedef enum
{
EnumOne = 0,
...
EnumSeventyFive = 74
} SeventyFiveFlagNames;
NS_INLINE BOOL testFlag(SeventyFiveFlags flags, SeventyFiveFlagNames bit)
{
return (flags.bits[bit >> 3] & (1 << (bit & 0x7))) != 0;
}
However you can also use the bitstring(3) functions/macros if you are OK with call-by-reference semantics. These create (heap or stack) bit strings of any length. Use your enum to provide symbolic names for the bit numbers rather than masks, e.g.:
#include <bitstring.h>
typedef enum
{
EnumOne = 0,
...
EnumSeventyFive = 74,
SeventyFiveFlagsSize = 75
} SeventyFiveFlagNames;
typedef bitstr_t *SeventyFiveFlags;
// local (stack) declaration & use
SeventyFiveFlags seventyFive;
bit_decl(seventyFive, SeventyFiveFlagsSize); // declare
bit_nclear(seventyFive, EnumOne, EnumSeventyFive); // set all false
if( bit_test(seventyFive, EnumFortyTwo) ) // test
You can always wrap this up as a class if heap allocation only is OK.
Maybe I am talking about something irrelevant.
I think having too much flag in an enum is not a good practise. Having this large amount of flag, there must be ways to group them up like:
enum
{
EnumNone=0,
EnumOne = 1<<0,
EnumTwo = 1<<1,
EnumThree = 1<<2,
EnumFour = 1<<3
};
typedef NSUInteger widthRelated;
enum
{
EnumNone=0,
EnumOne = 1<<0,
EnumTwo = 1<<1,
EnumThree = 1<<2,
EnumFour = 1<<3
};
typedef NSUInteger heightRelated;

Is there anything like a Java enum in Objective-C?

I have a situation in Objective-C where a Java-style enum would be very helpful. I have a set of layer types, and each layer has its own persistence value associated with it (stored in seconds). I want to keep these layer types in an enum, since they're too similar to make into separate classes, like so:
typedef enum {
ExplosionLayerType,
FireworkLayerType,
FireLayerType,
FireJetLayerType
} FXLayerType;
In Java, I could easily associate these two values with something like this:
public enum FXLayerType {
Explosion(3),
Firework(6),
Fire(7),
FireJet(-1);
private int persistence;
FXLayerType(int persistence) {
this.persistence = persistence;
}
}
Is there a simple way to create a sort of lightweight class like this in Objective-C, or will need to resort to more primitive methods?
EDIT:
Various people have suggested doing something like this:
typedef enum {
ExplosionLayerType = 3,
FireworkLayerType = 6
} FXLayerType;
This will not work for me, since I may have something like this (Java-style enum):
Explosion(3),
Firework(6),
Dust(3);
In Java, Dust and Explosion will be treated as unique values, but direct assignment with C enums will treat them as being exactly the same.
If you just want a primitive container for type and value, consider this approach:
typedef struct FXLayerValue {
FXLayerType type;
int value;
} FXLayerValue;
Then again, a class hierarchy may be worth consideration if things become complex or are better handled dynamically. Caveat: if you have a ton of objects to save and/or create, an objc type will be overkill and degrade performance.
Unfortunately, my Java-Fu isn't good enough to know all the lang differences for enums.
To emulate Java enum's we need something which is comparable (can be operands of == etc.), which can have fields, and is lightweight. This suggests structs, and optionally pointers to structs. Here is an example of the latter:
FXLayerType.h:
typedef const struct { int persistence; } FXLayerType;
extern FXLayerType * const LayerTypeExplosion;
extern FXLayerType * const LayerTypeFirework;
extern FXLayerType * const LayerTypeDust;
FXLayerType.m:
#import "FXLayerType.h"
const FXLayerType _LayerTypeExplosion = { 3 };
const FXLayerType _LayerTypeFirework = { 6 };
const FXLayerType _LayerTypeDust = { 3 };
FXLayerType * const LayerTypeExplosion = &_LayerTypeExplosion;
FXLayerType * const LayerTypeFirework = &_LayerTypeFirework;
FXLayerType * const LayerTypeDust = &_LayerTypeDust;
So FXLayerType itself is a constant struct, while as with Obj-C objects we always use pointers to these structs. The implementation creates 3 constant structs and 3 constant pointers to them.
We can now write code such as:
FXLayerType *a, *b;
a = LayerTypeDust;
b = LayerTypeExplosion;
NSLog(#"%d, %d\n", a == b, a->persistence == b->persistence);
Which will output "0, 1" - a and b are different enums (0) but have the same persistence (1). Note here a and b are not constant pointers, only the enum "literals" are defined as constants.
As written this has the disadvantage that you cannot switch on an enum value. However if that is needed just add a second field, say tag, and init it with a unique value using a real enum, say FXLayerStyleTag. You can also remove the indirection if you are happy to always compare tags (e.g. a.tag ==b.tag`). This gives you:
FXLayerType.h:
typedef enum { ExplosionTag, FireworkTag, DustTag } FXLayerTypeTag;
typedef struct { FXLayerTypeTag tag; int persistence; } FXLayerType;
extern const FXLayerType LayerTypeExplosion;
extern const FXLayerType LayerTypeFirework;
extern const FXLayerType LayerTypeDust;
FXLayerType.m:
#import "FXLayerType.h"
const FXLayerType LayerTypeExplosion = { ExplosionTag, 3 };
const FXLayerType LayerTypeFirework = { FireworkTag, 6 };
const FXLayerType LayerTypeDust = { DustTag, 3 };
Use:
FXLayerType a, b;
a = LayerTypeDust;
b = LayerTypeExplosion;
NSLog(#"%d, %d\n", a.tag == b.tag, a.persistence == b.persistence);
A difference between the two designs is the first passes around pointers while the second structures, which may be larger. You can combine them, to get switchable pointer-based enums - that is left as an exercise!
Both these designs also have the (dis)advantage that the number of enum "literals" can be extended at any time.
Actually you may assign values to the enum keys in C, as they are nothing but ints:
typedef enum {
LayerTypeExplosion = 3,
LayerTypeFirework = 6,
LayerTypeFire = 7,
LayerTypeFireJet = -1
} FXLayerType;
You may use them then simply as a restricted set of values, to be assigned to a variable of type FXLayerType.
FXLayerType myLayerType = LayerTypeFirework;
NSLog(#"Value of myLayerType = %i", myLayerType);
// => "Value of myLayerType = 6"
This is not 100% equivalent, but this might be an approach you could take in Objective-C. Basically, create several class-level convenience methods to construction the various configuration of FXLayerType.
#interface FXLayerType
{
#private
int persistence;
}
+ (FXLayerType*)fireworkLayerType;
+ (FXLayerType*)explosionLayerType;
+ (FXLayerType*)jetLayerType;
#end
#implementation FXLayerType
+ (FXLayerType*)explosionLayerTypeWithPersistence:(int)persistence
{
FXLayerType* layerType = [[FXLayerType new] autorelease];
layerType->persistence = persistence;
return layerType;
}
+ (FXLayerType*)explosionLayerType
{
return [self explosionLayerTypeWithPersistence:3];
}
+ (FXLayerType*)fireworkLayerType
{
return [self explosionLayerTypeWithPersistence:6];
}
+ (FXLayerType*)jetLayerType
{
return [self explosionLayerTypeWithPersistence:-1];
}
#end
Usage:
FXLayerType* aJetLayerType = [FXLayerType jetLayerType];
I have recently used the j2objc format for enums. It works rather nicely. Additionally you can auto generate your enums if you are trying to map directly from a java object.
https://code.google.com/p/j2objc/wiki/Enums
However, I did remove the j2objc specific classes from my "Enums". I did not want the additional dependencies.
The struct based answers look good on their face but fail when you try to add Objective-C objects into the struct. Given that limitation, truly emulating the Java-style enum may be more work than it is worth.