Objective-C / C giving enums default values - c

I read somewhere about giving enums default values like so:
typedef enum {
MarketNavigationTypeNone = 0,
MarketNavigationTypeHeirachy = 1,
MarketNavigationTypeMarket = 2
} MarketNavigationLevelType;
.. but i can't remember the value of doing this. If i don't give them default values - and then someone later on reorders the enum - what are the risks?
If i always use the enum name and don't even refer to them by their integer value, is there any risks?
The only possible problem i can think of is if i'm initialising an enum from an int value from a DB - and the enum is reordered - then the app would break.

That are not default values, you are giving them the values they will always have.
If you wouldn't initialize them explicitly, the first enumerators value is zero. For all others, if there is no initializer, their value is the value of the previous enumerator increased by one.
There are two reasons for giving them explicit values:
you don't want them to have the values they'd have otherwise
you want to make it clear what value they have (for you or other developers)
If you always refer to them by their name and never explicitly use an integral value for comparison or assignment, explicitly giving them a value is not needed.

In general this only matters if the enum is exposed to some kind of external API or it is going to be used to exchange data via data files or other means. If the enum is only every used within your app and nowhere else then the actual values don't matter.

Related

Alternative "null" value

It seems common to have the tail pointer at the end of a linked list be null (0).
What if I want to have two possible different "tails"?
My use case is a big integer representation that supports two's complement: I want to have a tail corresponding to "the rest of this number is zeros" and "the rest of this number is ones", where I can tell them apart just by performing a pointer equality.
It seems like this should be common enough to have standard practice, but it's hard to think of exactly what to search for. It seems somewhat arbitrary that we only get one "forbidden" pointer value (that will give a useful-ish error when accidentally dereferenced).
Options seem to include:
Use some arbitrary second value (like 1, or 0xdeadbeef). This seems evil. For one thing, I guess it needs to be aligned? Also, I will have obscure bugs if malloc happens to allocate a real linked list cell at the same address. Is there some region of memory malloc is guaranteed not to use?
Call malloc with a dummy non-zero size. This seems more sensible, but ideally I would have the pointer value be const, rather than requiring initialisation.
Take the address of something arbitrary, like a function defined in the file. This seems very evil, but does seem to lack any practical disadvantages (assuming it would work).
Given some ListItem type and a desired to have a ListItem * value that serves as a sentinel (also see sentinel node), we can simply define a ListItem object to serve that purpose:
ListItem SentinelObject;
ListItem * const SentinelValue = &SentinelObject;
This could also be made static if they will be used only in one translation unit.
The named object could be eliminated by using a compound literal:
ListItem * const SentinelValue = & (ListItem) {0};
(The initializer may need adjustment if 0 is not a suitable initailizer for the first member of ListItem.)
Alternately, wasting space could be avoided by overlapping the unused ListItem object with some other object:
union { SomeUsefulType SomeUsefulThing; ListItem SentinelObject; } MyUnion;
ListItem * const SentinelValue = &MyUnion.SentinelObject;
While this gives SomeUsefulThing and SentinelObject the same address, that is unlikely to be a problem given they have different types.

Eiffel: setting a constant with reference to other class constant

How to set a constant refering to another class constant in Eiffel?
Something like that doesn't compile unfortunately
Default_log_level: like {MY_LOGGER}.log_level = {MY_LOGGER}.Log_level_info
Constant attributes cannot be defined using other constant attributes in the current version of Eiffel.
Constant attributes can only be made of a manifest constant, but a possible workaround could be to use frozen once functions:
frozen Default_log_level: INTEGER
once
Result := {MY_LOGGER}.Log_level_info
ensure
definition: Result = {MY_LOGGER}.Log_level_info
end
frozen means that it cannot be redefined in descendant classes (like constant attributes).
Unfortunately, the type of once functions cannot rely on anchored types, hence the use of INTEGER instead of like {MY_LOGGER}.log_level.
And finally, the drawback with this solution is that it cannot be used where constant attributes are expected (e.g. in inspect instructions).

Remove a value from an enum without changing the other values

I have several enums that serve as type constants. For example:
enum item_type {
street,
town,
lake,
border,
...
}
The enum values are used in code to designate object types, and are written out to disk as part of data files. This mostly works well, but there is one drawback:
There is no way to remove an enum member (because it is no longer used) without changing the integer values of all subsequent members. So any such change would make the code incompatible with existing data files.
Is there some good technique for avoiding this problem? Maybe some preprocessor trick?
The only solution I can think of is to explicitly set all the integer values. While that would work, it is hard to read and manage for big enums.
Note: This problem comes from the source code of Navit, which uses several such "type enums" (though they are actually hidden behind some macros).
If you want to remove items very rarely, you could do something like
enum item_type {
street,
town,
//lake,
border = town+2,
...
}
i.e. only explicitly assign a value to the item immediately following the one you remove.
Since compatibility is very important to you, it'd be more reliable to just bite the bullet and explicitly number all items
enum item_type {
street = 0,
town = 1,
//lake = 2,
border = 3,
...
}
I ended up declaring a macro UNUSED, which expands to
UNUSED_<linenumber>. Then unused enum values can just be replaced by
UNUSED. The macro expands to a unique identifier on each line it is
used because otherwise the compiler would complain about duplicate enum
entries it were used multiple times inside one enum.
This is slightly ugly if you have many "gaps". Still, I chose this
solution over simonc's solution because it easy to read (keeps the regular enum values free of visual
clutter like three=zero+2) and does not require magic numbers.
Admittedly this only makes sense if the gaps are few and far between.
For large gaps simonc's solution looks better.
Complete example:
#include <stdio.h>
#define UNUSED UNUSED_P(__LINE__)
#define UNUSED_P(x) UNUSED_P2(x)
#define UNUSED_P2(x) UNUSED_##x
enum e {
zero,
UNUSED,
UNUSED,
three,
};
int main(void){
printf("int value of 'three': %d\n",three);
return 0;
}
The double replacement is adapted from, among others, this question:
c++ - How, exactly, does the double-stringize trick work? .

Sorting and managing numerous variables

My project has classes which, unavoidably, contain hundreds upon hundreds of variables that I'm always having to keep straight. For example, I'm always having to keep track of specific kinds of variables for a recurring set of "items" that occur inside of a class, where placing those variables between multiple classes would cause a lot of confusion.
How do I better sort my variables to keep from going crazy, especially when it comes time to save my data?
Am I missing something? Actionscript is an Object Oriented language, so you might have hundreds of variables, but unless you've somehow treated it like a grab bag and dumped it all in one place, everything should be to hand. Without knowing what all you're keeping track of, it's hard to give concrete advice, but here's an example from a current project I'm working on, which is a platform for building pre-employment assessments.
The basic unit is a Question. A Question has a stem, text that can go in the status bar, a collection of answers, and a collection of measures of things we're tracking about what the user does in that particular type of questions.
The measures are, again, their own type of object, and come in two "flavors": one that is used to track a time limit and one that isn't. The measure has a name (so we know where to write back to the database) and a value (which tells us what). Timed ones also have a property for the time limit.
When we need to time the question, we hand that measure to yet another object that counts the time down and a separate object that displays the time (if appropriate for the situation). The answers, known as distractors, have a label and a value that they can impart to the appropriate measure based on the user selection. For example, if a user selects "d", its value, "4" is transferred to the measure that stores the user's selection.
Once the user submits his answer, we loop through all the measures for the question and send those to the database. If those were not treated as a collection (in this case, a Vector), we'd have to know exactly what specific measures are being stored for each question and each question would have a very different structure that we'd have to dig through. So if looping through collections is your issue, I think you should revisit that idea. It saves a lot of code and is FAR more efficient than "var1", "var2", "var3."
If the part you think is unweildy is the type checking you have to do because literally anything could be in there, then Vector could be a good solution for you as long as you're using at least Flash Player 10.
So, in summary:
When you have a lot of related properties, write a Class that keeps all of those related bits and pieces together (like my Question).
When objects have 0-n "things" that are all of the same or very similar, use a collection of some sort, such as an Array or Vector, to allow you to iterate through them as a group and perform the same operation on each (for example, each Question is part of a larger grouping that allows each question to be presented in turn, and each question has a collection of distractors and another of measures.
These two concepts, used together, should help keep your information tidy and organized.
While I'm certain there are numerous ways of keeping arrays straight, I have found a method that works well for me. Best of all, it collapses large amounts of information into a handful of arrays that I can parse to an XML file or other storage method. I call this method my "indexed array system".
There are actually multiple ways to do this: creating a handful of 1-dimensional arrays, or creating 2-dimensional (or higher) array(s). Both work equally well, so choose the one that works best for your code. I'm only going to show the 1-dimensional method here. Those of you who are familiar with arrays can probably figure out how to rewrite this to use higher dimensional arrays.
I use Actionscript 3, but this approach should work with almost any programming or scripting language.
In this example, I'm trying to keep various "properties" of different "activities" straight. In this case, we'll say these properties are Level, High Score, and Play Count. We'll call the activities Pinball, Word Search, Maze, and Memory.
This method involves creating multiple arrays, one for each property, and creating constants that hold the integer "key" used for each activity.
We'll start by creating the constants, as integers. Constants work for this, because we never change them after compile. The value we put into each constant is the index the corresponding data will always be stored at in the arrays.
const pinball:int = 0;
const wordsearch:int = 1;
const maze:int = 2;
const memory:int = 3;
Now, we create the arrays. Remember, arrays start counting from zero. Since we want to be able to modify the values, this should be a regular variable.
Note, I am constructing the array to be the specific length we need, with the default value for the desired data type in each slot. I've used all integers here, but you can use just about any data type you need.
var highscore:Array = [0, 0, 0, 0];
var level:Array = [0, 0, 0, 0];
var playcount:Array = [0, 0, 0, 0];
So, we have a consistent "address" for each property, and we only had to create four constants, and three arrays, instead of 12 variables.
Now we need to create the functions to read and write to the arrays using this system. This is where the real beauty of the system comes in. Be sure this function is written in public scope if you want to read/write the arrays from outside this class.
To create the function that gets data from the arrays, we need two arguments: the name of the activity and the name of the property. We also want to set up this function to return a value of any type.
GOTCHA WARNING: In Actionscript 3, this won't work in static classes or functions, as it relies on the "this" keyword.
public function fetchData(act:String, prop:String):*
{
var r:*;
r = this[prop][this[act]];
return r;
}
That queer bit of code, r = this[prop][this[act]], simply uses the provided strings "act" and "prop" as the names of the constant and array, and sets the resulting value to r. Thus, if you feed the function the parameters ("maze", "highscore"), that code will essentially act like r = highscore[2] (remember, this[act] returns the integer value assigned to it.)
The writing method works essentially the same way, except we need one additional argument, the data to be written. This argument needs to be able to accept any
GOTCHA WARNING: One significant drawback to this system with strict typing languages is that you must remember the data type for the array you're writing to. The compiler cannot catch these type errors, so your program will simply throw a fatal error if it tries to write the wrong value type.
One clever way around this is to create different functions for different data types, so passing the wrong data type in an argument will trigger a compile-time error.
public function writeData(act:String, prop:String, val:*):void
{
this[prop][this[act]] = val;
}
Now, we just have one additional problem. What happens if we pass an activity or property name that doesn't exist? To protect against this, we just need one more function.
This function will validate a provided constant or variable key by attempting to access it, and catching the resulting fatal error, returning false instead. If the key is valid, it will return true.
function validateName(ID:String):Boolean
{
var checkthis:*
var r:Boolean = true;
try
{
checkthis = this[ID];
}
catch (error:ReferenceError)
{
r = false;
}
return r;
}
Now, we just need to adjust our other two functions to take advantage of this. We'll wrap the function's code inside an if statement.
If one of the keys is invalid, the function will do nothing - it will fail silently. To get around this, just put a trace (a.k.a. print) statement or a non-fatal error in the else construct.
public function fetchData(act:String, prop:String):*
{
var r:*;
if(validateName(act) && validateName(prop))
{
r = this[prop][this[act]];
return r;
}
}
public function writeData(act:String, prop:String, val:*):void
{
if(validateName(act) && validateName(prop))
{
this[prop][this[act]] = val;
}
}
Now, to use these functions, you simply need to use one line of code each. For the example, we'll say we have a text object in the GUI that shows the high score, called txtHighScore. I've omitted the necessary typecasting for the sake of the example.
//Get the high score.
txtHighScore.text = fetchData("maze", "highscore");
//Write the new high score.
writeData("maze", "highscore", txtHighScore.text);
I hope ya'll will find this tutorial useful in sorting and managing your variables.
(Afternote: You can probably do something similar with dictionaries or databases, but I prefer the flexibility with this method.)

Why do I have to write *myPointerVar only SOMETIMES in Objective-C?

That's an issue I still don't understand.
Sometimes I have to write:
NSString* myVariable;
myVariable = #"Hey!";
Then, for example I define a Structure "DemoStruct" and get an Variable that uses it. Lets say I have a Structure that has x and y vars from type double.
I want to pass this var to a method which then manipulates my var, and I want that this manipulation has effect on the context from which I passed the var to that method. So I need a pointer, right.
I pass it to the method like that:
[someObject someMethod:&myVarThatUsesTheStruct]
that method now looks like that:
- (void)someMethod:(DemoStruct*)myVar {
(*myVar).x += 10;
}
Before the call, the component x of the struct was lets say 1000. Now, 10 is added and it is 1010 after the method call.
But I really really hardly dont get it why I have to use the Asterisk * for myVar in the Method, since I say already in the Method Header that myVar is a POINTER to a DemoStruct. I just pass with &myVarThatUsesTheStruct the memory address.
Can someone explain why this is like it is?
As you say, myVar is a pointer. As such, myVar.x is not correct: it would by a field of a pointer, which has no sense in C/Objective-C.
If you want to access to the variable pointed to by a pointer, you have to add the asterisk: myVar is a pointer, *myVar is the variable pointed to by myVar.
Moreover, in your case, you can use a special construct of C by writing myVar->x, which is strictly equivalent to (*myVar).x.
All of this is standard C, not specific to Objective-C.
About your first example, you don't have to put an asterisk because you change the value of the pointer, not the value of the variable: myVariable is a pointer to an object which at declaration time is assigned the nil value. The next instruction (myVariable = #"Hey!") is an assignment of pointer values: #"Hey!" is a pointer to a NSString object. The value of this pointer (not the value of the pointed constant) is assigned to myVariable, which then points to the object #"Hey!".
Yes, this is diffucult to follow at first time...
* is the dereference operator. All that *myVar means is "Get me the thing that the pointer myVar points to". You need this distinction because you need to tell the computer that you want to change the thing that myVar points to, not myVar itself.
taken from the learning objective c link via the developers portal for iphone devs:
Objective-C supports both strong and weak typing for variables
containing objects. Strongly typed variables include the class name in
the variable type declaration. Weakly typed variables use the type id
for the object instead. Weakly typed variables are used frequently for
things such as collection classes, where the exact type of the objects
in a collection may be unknown. If you are used to using strongly
typed languages, you might think that the use of weakly typed
variables would cause problems, but they actually provide tremendous
flexibility and allow for much greater dynamism in Objective-C
programs.
The following example shows strongly and weakly typed variable
declarations:
MyClass *myObject1; // Strong typing
id myObject2; // Weak typing
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.

Resources