All values of an enum in an NSArray? - objective-c

Hi all I have an enum type that holds my error codes.
The problem is that they are not sequential i.e.
enum{
ErrorCode1 = 1,
ErrorCode2 = 4,
ErrorCode3 = 74
}; typedef NSInteger MyErroCodes;
Also there are maybe 50 codes + so I really wouldn't want to have to duplicate the data or do it manually, which is what I've seen so far in my searches. Any help would be greatly appreciated.

The enum construct only exists at compile time. At run time, your MyErrorCodes instances are plain integers, and the ErrorCodeN values are just plain integer constants. There is no way to extract metadata from your enum in runtime (well, maybe there is in the debug info etc, but you don't want to go there...).
I suggest:
Create a small script (Python, Perl or whatnot) to generate functions that map the numeric code to string values. In XCode, you can even run code generators during the compilation phase if you really want.
Use metaprogramming or preprocessor macros to generate these functions during compilation. This requires some thought, but it can be done.

this is often accomplished using an include of a file which contains all the values within some body and sometimes using macros:
ErrorCode_enum.h
MON_ENUM_VALUE(ErrorCode1, 1)
MON_ENUM_VALUE(ErrorCode2, 4)
MON_ENUM_VALUE(ErrorCode3, 74)
where MON_ENUM_VALUE would be a variable macro expansion.
and your enum declaration might take this form:
enum {
#include "mon_enum_value_begin.h" // defines MON_ENUM_VALUE and such
#include "ErrorCode_enum.h"
#include "mon_enum_value_end.h" // undefines MON_ENUM_VALUE and everything else defined in mon_enum_value_begin.h
};
typedef NSInteger MyErroCodes;
then later you might write:
#include "mon_enum_NSNumber_begin.h" // defines MON_ENUM_VALUE and such
#include "ErrorCode_enum.h"
#include "mon_enum_NSNumber_end.h" // undefines MON_ENUM_VALUE and…
or
#include "mon_enum_NSError_begin.h" // defines MON_ENUM_VALUE and such
#include "ErrorCode_enum.h"
#include "mon_enum_NSError_end.h" // undefines MON_ENUM_VALUE and…
which may add or stringize those tags and values to other types.
Personally, I think the macros are gross, and just take alternate approaches (which, admittedly, may be more tedious to write).

Related

How to change the values defined in header file in embedded c during runtime?

I am working on a project using MSP430FR6047 and there is certain header file I need to access and change parameters previously defined.
At the moment I have to flash the MCU with modified header file every time I change the parameter but I was exploring if there is another option to do theses changes without flashing the new code, preferably by UART or some other communication protocol.
So my question is how to change these parameters during runtime? Does any one know where should I start?
Thanks
A running program cannot change its source code, supposed that you mean something like #define PARAMETER 23. You need variables instead of constants.
One primitive solution is this:
Invent a global variable per parameter, declare all of them in an extra header file and define all of them in an extra source file for better maintenance.
In the new header file undefine all parameter macros and redefine them to use the variable instead of the literals.
In the using source files, include the original header file, after that include your new header file.
Initialize the variables initially, and change parameters as you wish during run time. (Initialization could be done in the new source file.)
This solution avoids heavy editing the using source files and leaves the original header file intact.
Example:
/* original.h */
#define PARAMETER 23
int f(void); /* returns PARAMETER */
/* new.h */
#if defined(PARAMETER)
#undef PARAMETER
#define PARAMETER parameter
#endif
extern int parameter;
/* new.c */
#include "new.h" /* ensures that declarations and definitions match */
int parameter = 23;
/* original.c */
#include "original.h"
#include "new.h"
int f(void) {
return PARAMETER;
}
/* main.c */
#include <stdio.h>
#include "original.h"
#include "new.h"
int main(void) {
PARAMETER = 42;
printf("%d\n", f());
}
If you like to change the original source code, feel free to get rid of all this preprocessor stuff, and directly use variables instead of constants. But then you should re-think your design and provide parameters as arguments to existing or new functions. Global variables should be avoided, reasons are left as an exercise to you.
There are 2 cases which change parameter in header file.
Case 1: Header define default value
For example, in header file you have:
#define DEFAULT_VALUE 10
then in .c file if it is using like:
if (a < DEFAULT_VALUE)
{ /* Do something */ }
If this is the case you could update as following:
Modified the original line:
if (a < var_DefaultValue)
{ /* Do something */ }
With var_DefaultValue is global variable:
int var_DefaultValue = DEFAULT_VALUE;
By default, this will work as original.
If you want to change value, you could create a thread to receive new value somewhere and then update to var_DefaultValue.
Case 2: Header file define some precompile tag. For example:
#define DEFAULT_FEATURE 1
and in .c file you refer to feature as following:
#if DEFAULT_FEATURE
/* Do Something */
#endif
For this case, it is impossible to change it by any mean.

How to redefine `YYSTYPE` in `bison/yacc`?

I define a user class to hold all object. But the yacc is going to made a header file, which the yylval's type must be YYSTYPE. If I do not use %union, it will hold it as a int. But if I use %union, it will a union. and union is ugly - It cannot hold a class or a shared_ptr (can but not a good idea), It only want me to use pointer.
I just want to make YYSTYPE has a type as a user class type. How can I do it?
Don't use YYSTYPE.
With bison -- which is what you are actually using as a yacc implementation-- the correct way to define the semantic value type is
%define api.value.type { MyType }
If you require that one or more header files be included for the declaration to be valid, put them inside a %code requires block:
%code requires {
#include "MyType.h"
}
The code generated by these two directives is copied into the header file which bison produces, so other files need only include the generated header file.
Warning: Note that unless you use bison's C++ interface, the semantic value type must be trivially copyable, which will eliminate most standard C++ library types. Failing to obey this rule will produce undefined behaviour which may go undetected until you attempt to parse a sufficiently complex input. In other words, tests with simple inputs may not reveal the bug.
As you see, the source file that made by lex and yacc need the header file that made by yacc.
the header is short so we can look for some solution in it.
the part that define the type of yylval is this:
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
so we can define YYSTYPE before we include the yacc's header file, looks like:
#include "your-header-file-that-define-the-class.h"
#define YYSTYPE your-class-type
#include "the-header-file-that-made-by-yacc.h"

Two different CMake difinitions

With CMake when some definitions are defined they are defined in this way:
add_definitions(-DMY_DEFINITION)
Sometimes I see people make the definitions in a different way:
add_definitions(-DMY_DEFINITION=1)
Then my question is what's the difference between them in the generated C++ project. Thanks.
This is not really related to CMake but more to the C/++ compiler.
In the code the difference is the same between :
#define MY_DEFINITION
and
#define MY_DEFINITION 1
Actually there's not need to define a value for a C/++ macro if the only thing you want is to know if the macro exists (has been defined), like a "flag". Best example is the header include guards :
#ifndef MYHEADER
#define MYHEADER
// ...
#endif
But sometimes people prefer setting a value (like =1) even if they don't need it, because it's more exhaustive, or clear.
More generally speaking when you affect a value to a macro it is because you expect the macro name to be expanded to the value. When not you just expect the value to exist. The way tests are done may be different :
With -DMY_DEFINITION:
#ifdef MY_DEFINITION
// Do something
#else
// Do somthing else
#endif
With -DMY_DEFINITION=1
#if MY_DEFINITION
// Do something
#else
// Do somthing else
#endif

#define vs const in Objective-C

I'm new to Objective-C, and I have a few questions regarding const and the preprocessing directive #define.
First, I found that it's not possible to define the type of the constant using #define. Why is that?
Second, are there any advantages to use one of them over the another one?
Finally, which way is more efficient and/or more secure?
First, I found that its not possible to define the type of the constant using #define, why is that?
Why is what? It's not true:
#define MY_INT_CONSTANT ((int) 12345)
Second, are there any advantages to use one of them over the another one?
Yes. #define defines a macro which is replaced even before compilation starts. const merely modifies a variable so that the compiler will flag an error if you try to change it. There are contexts in which you can use a #define but you can't use a const (although I'm struggling to find one using the latest clang). In theory, a const takes up space in the executable and requires a reference to memory, but in practice this is insignificant and may be optimised away by the compiler.
consts are much more compiler and debugger friendly than #defines. In most cases, this is the overriding point you should consider when making a decision on which one to use.
Just thought of a context in which you can use #define but not const. If you have a constant that you want to use in lots of .c files, with a #define you just stick it in a header. With a const you have to have a definition in a C file and
// in a C file
const int MY_INT_CONST = 12345;
// in a header
extern const int MY_INT_CONST;
in a header. MY_INT_CONST can't be used as the size of a static or global scope array in any C file except the one it is defined in.
However, for integer constants you can use an enum. In fact that is what Apple does almost invariably. This has all the advantages of both #defines and consts but only works for integer constants.
// In a header
enum
{
MY_INT_CONST = 12345,
};
Finally, which way is more efficient and/or more secure?
#define is more efficient in theory although, as I said, modern compilers probably ensure there is little difference. #define is more secure in that it is always a compiler error to try to assign to it
#define FOO 5
// ....
FOO = 6; // Always a syntax error
consts can be tricked into being assigned to although the compiler might issue warnings:
const int FOO = 5;
// ...
(int) FOO = 6; // Can make this compile
Depending on the platform, the assignment might still fail at run time if the constant is placed in a read only segment and it's officially undefined behaviour according to the C standard.
Personally, for integer constants, I always use enums for constants of other types, I use const unless I have a very good reason not to.
From a C coder:
A const is simply a variable whose content cannot be changed.
#define name value, however, is a preprocessor command that replaces all instances of the name with value.
For instance, if you #define defTest 5, all instances of defTest in your code will be replaced with 5 when you compile.
It is important to understand the difference between the #define and the const instructions which are not meant to the same things.
const
const is used to generate an object from the asked type that will be, once initialised, constant. It means that it is an object in the program memory and can be used as readonly.
The object is generated every time the program is launched.
#define
#define is used in order to ease the code readability and future modifications. When using a define, you only mask a value behind a name. Hence when working with a rectangle you can define width and height with corresponding values. Then in the code, it will be easier to read since instead of numbers there will be names.
If later you decide to change the value for the width you would only have to change it in the define instead of a boring and dangerous find/replace in your whole file.
When compiling, the preprocessor will replace all the defined name by the values in the code. Hence, there is no time lost using them.
In addition to other peoples comments, errors using #define are notoriously difficult to debug as the pre-processor gets hold of them before the compiler.
Since pre-processor directives are frowned upon, I suggest using a const. You can't specify a type with a pre-processor because a pre-processor directive is resolved before compilation. Well, you can, but something like:
#define DEFINE_INT(name,value) const int name = value;
and use it as
DEFINE_INT(x,42)
which would be seen by the compiler as
const int x = 42;
First, I found that its not possible to define the type of the constant using #define, why is that?
You can, see my first snippet.
Second, are there any advantages to use one of them over the another one?
Generally having a const instead of a pre-processor directive helps with debugging, not as much in this case (but still does).
Finally, which way is more efficient and/or more secure?
Both are as efficient. I'd say the macro can potentially be more secure as it can't be changed during run-time, whereas a variable could.
I have used #define before to help create more methods out of one method like if I have something like.
// This method takes up to 4 numbers, we don't care what the method does with these numbers.
void doSomeCalculationWithMultipleNumbers:(NSNumber *)num1 Number2:(NSNumber *)num2 Number3:(NSNumber *)num23 Number3:(NSNumber *)num3;
But I also what to have a method that only takes 3 numbers and 2 numbers so instead of writing two new methods I am going to use the same one using the #define, like so.
#define doCalculationWithFourNumbers(num1, num2, num3, num4) \
doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), (num4))
#define doCalculationWithThreeNumbers(num1, num2, num3) \
doSomeCalculationWithMultipleNumbers((num1), (num2), (num3), nil)
#define doCalculationWithTwoNumbers(num1, num2) \
doSomeCalculationWithMultipleNumbers((num1), (num2), nil, nil)
I think this is a pretty cool thing to have, I know you can go straight to the method and just put nil in the spaces you don't want but if you are building a library it is very useful. Also this is how
NSLocalizedString(<#key#>, <#comment#>)
NSLocalizedStringFromTable(<#key#>, <#tbl#>, <#comment#>)
NSLocalizedStringFromTableInBundle(<#key#>, <#tbl#>, <#bundle#>, <#comment#>)
are done.
Whereas I don't believe you can do this with constants. But constants do have there benefits over #define like you can't specify a type with a #define because it is a pre-processor directive that is resolved before compilation, and if you get an error with #define they are harder to debug then constants. Both have there benefits and downsides but I would say it all depends on the programmer to which one you decided to use. I have written a library with both them in using the #define to do what I have shown and constants for declaring constant variables which I need to specify a type on.

#include <malloc.h> -- Xcode

I have an interesting problem where I can't include malloc.h in my project.
I need malloc.h for Paul Nettle's mmgr tool (I'm not keen on using instruments)
Problem is I can't find the system library for memalign.
Xcode keeps failing because it cannot this definition & neither can I.
Anyone else seen this?!
If you just need to use malloc then you can grab it from the stdlib like so:
#include <stdlib.h>
Otherwise, you can directly call malloc.h like so:
#include <malloc/malloc.h>
EDIT:
A posix_memalign() exists in stdlib.h. The implementation looks like:
int posix_memalign(void **, size_t, size_t);
Perhaps you can make an alias to this and use it?