As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
For example, I recently came across this in the linux kernel:
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
So, in your code, if you have some structure which must be, say a multiple of 8 bytes in size, maybe because of some hardware constraints, you can do:
BUILD_BUG_ON((sizeof(struct mystruct) % 8) != 0);
and it won't compile unless the size of struct mystruct is a multiple of 8, and if it is a multiple of 8, no runtime code is generated at all.
Another trick I know is from the book "Graphics Gems" which allows a single header file to both declare and initialize variables in one module while in other modules using that module, merely declare them as externs.
#ifdef DEFINE_MYHEADER_GLOBALS
#define GLOBAL
#define INIT(x, y) (x) = (y)
#else
#define GLOBAL extern
#define INIT(x, y)
#endif
GLOBAL int INIT(x, 0);
GLOBAL int somefunc(int a, int b);
With that, the code which defines x and somefunc does:
#define DEFINE_MYHEADER_GLOBALS
#include "the_above_header_file.h"
while code that's merely using x and somefunc() does:
#include "the_above_header_file.h"
So you get one header file that declares both instances of globals and function prototypes where they are needed, and the corresponding extern declarations.
So, what are your favorite C programming tricks along those lines?
C99 offers some really cool stuff using anonymous arrays:
Removing pointless variables
{
int yes=1;
setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
}
becomes
setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));
Passing a Variable Amount of Arguments
void func(type* values) {
while(*values) {
x = *values++;
/* do whatever with x */
}
}
func((type[]){val1,val2,val3,val4,0});
Static linked lists
int main() {
struct llist { int a; struct llist* next;};
#define cons(x,y) (struct llist[]){{x,y}}
struct llist *list=cons(1, cons(2, cons(3, cons(4, NULL))));
struct llist *p = list;
while(p != 0) {
printf("%d\n", p->a);
p = p->next;
}
}
Any I'm sure many other cool techniques I haven't thought of.
While reading Quake 2 source code I came up with something like this:
double normals[][] = {
#include "normals.txt"
};
(more or less, I don't have the code handy to check it now).
Since then, a new world of creative use of the preprocessor opened in front of my eyes. I no longer include just headers, but entire chunks of code now and then (it improves reusability a lot) :-p
Thanks John Carmack! xD
I'm fond of using = {0}; to initialize structures without needing to call memset.
struct something X = {0};
This will initialize all of the members of the struct (or array) to zero (but not any padding bytes - use memset if you need to zero those as well).
But you should be aware there are some issues with this for large, dynamically allocated structures.
If we are talking about c tricks my favourite has to be Duff's Device for loop unrolling! I'm just waiting for the right opportunity to come along for me to actually use it in anger...
using __FILE__ and __LINE__ for debugging
#define WHERE fprintf(stderr,"[LOG]%s:%d\n",__FILE__,__LINE__);
In C99
typedef struct{
int value;
int otherValue;
} s;
s test = {.value = 15, .otherValue = 16};
/* or */
int a[100] = {1,2,[50]=3,4,5,[23]=6,7};
Once a mate of mine and I redefined return to find a tricky stack corruption bug.
Something like:
#define return DoSomeStackCheckStuff, return
I like the "struct hack" for having a dynamically sized object. This site explains it pretty well too (though they refer to the C99 version where you can write "str[]" as the last member of a struct). you could make a string "object" like this:
struct X {
int len;
char str[1];
};
int n = strlen("hello world");
struct X *string = malloc(sizeof(struct X) + n);
strcpy(string->str, "hello world");
string->len = n;
here, we've allocated a structure of type X on the heap that is the size of an int (for len), plus the length of "hello world", plus 1 (since str1 is included in the sizeof(X).
It is generally useful when you want to have a "header" right before some variable length data in the same block.
Object oriented code with C, by emulating classes.
Simply create a struct and a set of functions that take a pointer to that struct as a first parameter.
Instead of
printf("counter=%d\n",counter);
Use
#define print_dec(var) printf("%s=%d\n",#var,var);
print_dec(counter);
Using a stupid macro trick to make record definitions easier to maintain.
#define COLUMNS(S,E) [(E) - (S) + 1]
typedef struct
{
char studentNumber COLUMNS( 1, 9);
char firstName COLUMNS(10, 30);
char lastName COLUMNS(31, 51);
} StudentRecord;
For creating a variable which is read-only in all modules except the one it's declared in:
// Header1.h:
#ifndef SOURCE1_C
extern const int MyVar;
#endif
// Source1.c:
#define SOURCE1_C
#include Header1.h // MyVar isn't seen in the header
int MyVar; // Declared in this file, and is writeable
// Source2.c
#include Header1.h // MyVar is seen as a constant, declared elsewhere
Bit-shifts are only defined up to a shift-amount of 31 (on a 32 bit integer)..
What do you do if you want to have a computed shift that need to work with higher shift-values as well? Here is how the Theora vide-codec does it:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
return (a>>(v>>1))>>((v+1)>>1);
}
Or much more readable:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
unsigned int halfshift = v>>1;
unsigned int otherhalf = (v+1)>>1;
return (a >> halfshift) >> otherhalf;
}
Performing the task the way shown above is a good deal faster than using a branch like this:
unsigned int shiftmystuff (unsigned int a, unsigned int v)
{
if (v<=31)
return a>>v;
else
return 0;
}
Declaring array's of pointer to functions for implementing finite state machines.
int (* fsm[])(void) = { ... }
The most pleasing advantage is that it is simple to force each stimulus/state to check all code paths.
In an embedded system, I'll often map an ISR to point to such a table and revector it as needed (outside the ISR).
Another nice pre-processor "trick" is to use the "#" character to print debugging expressions. For example:
#define MY_ASSERT(cond) \
do { \
if( !(cond) ) { \
printf("MY_ASSERT(%s) failed\n", #cond); \
exit(-1); \
} \
} while( 0 )
edit: the code below only works on C++. Thanks to smcameron and Evan Teran.
Yes, the compile time assert is always great. It can also be written as:
#define COMPILE_ASSERT(cond)\
typedef char __compile_time_assert[ (cond) ? 0 : -1]
I wouldn't really call it a favorite trick, since I've never used it, but the mention of Duff's Device reminded me of this article about implementing Coroutines in C. It always gives me a chuckle, but I'm sure it could be useful some time.
#if TESTMODE == 1
debug=1;
while(0); // Get attention
#endif
The while(0); has no effect on the program, but the compiler will issue a warning about "this does nothing", which is enough to get me to go look at the offending line and then see the real reason I wanted to call attention to it.
I'm a fan of xor hacks:
Swap 2 pointers without third temp pointer:
int * a;
int * b;
a ^= b;
b ^= a;
a ^= b;
Or I really like the xor linked list with only one pointer. (http://en.wikipedia.org/wiki/XOR_linked_list)
Each node in the linked list is the Xor of the previous node and the next node. To traverse forward, the address of the nodes are found in the following manner :
LLNode * first = head;
LLNode * second = first.linked_nodes;
LLNode * third = second.linked_nodes ^ first;
LLNode * fourth = third.linked_nodes ^ second;
etc.
or to traverse backwards:
LLNode * last = tail;
LLNode * second_to_last = last.linked_nodes;
LLNode * third_to_last = second_to_last.linked_nodes ^ last;
LLNode * fourth_to_last = third_to_last.linked_nodes ^ second_to_last;
etc.
While not terribly useful (you can't start traversing from an arbitrary node) I find it to be very cool.
This one comes from the book 'Enough rope to shoot yourself in the foot':
In the header declare
#ifndef RELEASE
# define D(x) do { x; } while (0)
#else
# define D(x)
#endif
In your code place testing statements eg:
D(printf("Test statement\n"));
The do/while helps in case the contents of the macro expand to multiple statements.
The statement will only be printed if '-D RELEASE' flag for compiler is not used.
You can then eg. pass the flag to your makefile etc.
Not sure how this works in windows but in *nix it works well
Rusty actually produced a whole set of build conditionals in ccan, check out the build assert module:
#include <stddef.h>
#include <ccan/build_assert/build_assert.h>
struct foo {
char string[5];
int x;
};
char *foo_string(struct foo *foo)
{
// This trick requires that the string be first in the structure
BUILD_ASSERT(offsetof(struct foo, string) == 0);
return (char *)foo;
}
There are lots of other helpful macros in the actual header, which are easy to drop into place.
I try, with all of my might to resist the pull of the dark side (and preprocessor abuse) by sticking mostly to inline functions, but I do enjoy clever, useful macros like the ones you described.
Two good source books for this sort of stuff are The Practice of Programming and Writing Solid Code. One of them (I don't remember which) says: Prefer enum to #define where you can, because enum gets checked by the compiler.
Not specific to C, but I've always liked the XOR operator. One cool thing it can do is "swap without a temp value":
int a = 1;
int b = 2;
printf("a = %d, b = %d\n", a, b);
a ^= b;
b ^= a;
a ^= b;
printf("a = %d, b = %d\n", a, b);
Result:
a = 1, b = 2
a = 2, b = 1
See "Hidden features of C" question.
I like the concept of container_of used for example in lists. Basically, you do not need to specify next and last fields for each structure which will be in the list. Instead, you append the list structure header to actual linked items.
Have a look on include/linux/list.h for real-life examples.
I think the use of userdata pointers is pretty neat. A fashion losing ground nowdays. It's not so much a C feature but is pretty easy to use in C.
I use X-Macros to to let the pre-compiler generate code. They are especially useful for defining error values and associated error strings in one place, but they can go far beyond that.
Our codebase has a trick similar to
#ifdef DEBUG
#define my_malloc(amt) my_malloc_debug(amt, __FILE__, __LINE__)
void * my_malloc_debug(int amt, char* file, int line)
#else
void * my_malloc(int amt)
#endif
{
//remember file and line no. for this malloc in debug mode
}
which allows for the tracking of memory leaks in debug mode. I always thought this was cool.
Fun with macros:
#define SOME_ENUMS(F) \
F(ZERO, zero) \
F(ONE, one) \
F(TWO, two)
/* Now define the constant values. See how succinct this is. */
enum Constants {
#define DEFINE_ENUM(A, B) A,
SOME_ENUMS(DEFINE_ENUMS)
#undef DEFINE_ENUM
};
/* Now a function to return the name of an enum: */
const char *ToString(int c) {
switch (c) {
default: return NULL; /* Or whatever. */
#define CASE_MACRO(A, B) case A: return #b;
SOME_ENUMS(CASE_MACRO)
#undef CASE_MACRO
}
}
Here is an example how to make C code completly unaware about what is actually used of HW for running the app. The main.c does the setup and then the free layer can be implemented on any compiler/arch. I think it is quite neat for abstracting C code a bit, so it does not get to be to spesific.
Adding a complete compilable example here.
/* free.h */
#ifndef _FREE_H_
#define _FREE_H_
#include <stdio.h>
#include <string.h>
typedef unsigned char ubyte;
typedef void (*F_ParameterlessFunction)() ;
typedef void (*F_CommandFunction)(ubyte byte) ;
void F_SetupLowerLayer (
F_ParameterlessFunction initRequest,
F_CommandFunction sending_command,
F_CommandFunction *receiving_command);
#endif
/* free.c */
static F_ParameterlessFunction Init_Lower_Layer = NULL;
static F_CommandFunction Send_Command = NULL;
static ubyte init = 0;
void recieve_value(ubyte my_input)
{
if(init == 0)
{
Init_Lower_Layer();
init = 1;
}
printf("Receiving 0x%02x\n",my_input);
Send_Command(++my_input);
}
void F_SetupLowerLayer (
F_ParameterlessFunction initRequest,
F_CommandFunction sending_command,
F_CommandFunction *receiving_command)
{
Init_Lower_Layer = initRequest;
Send_Command = sending_command;
*receiving_command = &recieve_value;
}
/* main.c */
int my_hw_do_init()
{
printf("Doing HW init\n");
return 0;
}
int my_hw_do_sending(ubyte send_this)
{
printf("doing HW sending 0x%02x\n",send_this);
return 0;
}
F_CommandFunction my_hw_send_to_read = NULL;
int main (void)
{
ubyte rx = 0x40;
F_SetupLowerLayer(my_hw_do_init,my_hw_do_sending,&my_hw_send_to_read);
my_hw_send_to_read(rx);
getchar();
return 0;
}
if(---------)
printf("hello");
else
printf("hi");
Fill in the blanks so that neither hello nor hi would appear in output.
ans: fclose(stdout)
Related
There are a lot of questions out there about forward declarations and opaque types, but most seem to be from the perspective of the library author, or people trying to use incomplete types without pointers or some such.
I'm using a library whose interface accepts/returns FOO * pointers. I'd like to confirm that I cannot (or should not) somehow forward-declare FOO or FOO * in my header file (which defines a struct with a FOO * member).
I do know that I could just #include <library.h> in both my header and my .c file, but since this is really just a learning project, I wanted to get clarification. (On the one hand, it seems like a forward-declaration might be possible, since my struct member is only a pointer and thus its size is known without knowing what FOO is—but on the other hand, I don't know if it's valid/smart to typedef something to FOO when the library is already doing that.)
Thanks in advance!
Assuming you never need to dereference the pointer, then you can use an opaque type pointer if you know the struct tag name for it:
typedef struct FOO FOO;
You can now create FOO * variables, and use them. And you probably could find the structure tag from the header file, but you should be aware that the library owners could change it at any time.
It is still usually best to include the official header, but if most of your code is not accessing the actual library, just passing around a handle to something returned by the library, you can avoid the 'cost' of including the actual header. You should measure what that cost is before deciding on what is probably premature optimization. It might be argued that if you have to ask the question, you don't know enough to be sure of doing it right, and you're in danger of getting burnt.
Note that you cannot create actual variables of the type; for that to work, the compiler needs to know how big the structure actually is, which means you need the details from the header.
Strictly speaking, if you don't know the tag name, that won't work. And likewise, if the structure doesn't have a tag, you can't do it either. And if it isn't a structure type, you can't do it.
Note that if you know the structure tag, you can also write:
struct FOO *fp;
If you have to get inventive, everything works for passing around pointers until you reach the point where you need to access the actual library functions. Then you need the actual library header (to make sure the information is right), and if your structure tag is wrong, all hell breaks loose. So, if you're going to play this game, make sure you get the structure tag correct.
Note that C11 allows a typedef to be repeated as long as it is the same each time, whereas earlier versions of C did not allow that. This can be a considerable help.
Working example
This is close to a minimal example that shows how it might be done. It assumes C11 where the repeated typedef is legitimate. It won't work for C99 or C89/C90 because the typedef for FOO is repeated when projfunc.c is compiled. (There are various ways you can adapt it so that it will work in C99 or earlier, but they're messier, using #ifdef or similar around the project.h typedef — since the presumption is that you can't alter library.h; if you can, it is part of your project after all.)
The project.h header is used primarily by the general code that belongs to the project that uses the library defining FOO — which is represented by projmain.c in this example. It can be used on its own, or with library.h, which is illustrated by projfunc.c which is the project code that actually interfaces to the library and makes calls to the library. The file library.c only uses library.h.
You can play with alternative declarations of FOO in project.h to see what goes wrong where. For example, typedef struct BAR FOO; will fail; so will typedef struct FOO *FOO;.
project.h
#ifndef PROJECT_H_INCLUDED
#define PROJECT_H_INCLUDED
typedef struct FOO FOO;
typedef struct Project
{
FOO *foop;
char *name;
int max;
double ratio;
} Project;
extern int proj_function(Project *pj);
#endif /* PROJECT_H_INCLUDED */
library.h
#ifndef LIBRARY_H_INCLUDED
#define LIBRARY_H_INCLUDED
typedef struct FOO
{
int x;
int y;
} FOO;
extern FOO *foo_open(const char *file);
extern int foo_close(FOO *foop);
extern int foo_read(FOO *foop, int *x, int *y);
extern int foo_write(FOO *foop, int x, int y);
#endif /* LIBRARY_H_INCLUDED */
projmain.c
#include "project.h"
int main(void)
{
Project pj = { 0, 0, 0, 0.0 };
if (proj_function(&pj) != 0)
return 1;
return 0;
}
projfunc.c
#include "project.h"
#include "library.h"
#include <stdio.h>
int proj_function(Project *pj)
{
int x, y;
pj->foop = foo_open("classic-mode");
if (foo_write(pj->foop, 1, 2) < 0)
{
foo_close(pj->foop);
return -1;
}
if (foo_read(pj->foop, &x, &y) < 0)
{
foo_close(pj->foop);
return -1;
}
printf("x = %d, y = %d\n", x, y);
return 0;
}
library.c
#include "library.h"
#include <assert.h>
static FOO foo = { 0, 0 };
FOO *foo_open(const char *file)
{
assert(file != 0);
return &foo;
}
int foo_close(FOO *foop)
{
assert(foop == &foo);
foo.x = foo.y = 0;
return 0;
}
int foo_read(FOO *foop, int *x, int *y)
{
assert(foop == &foo);
*x = foop->x + 1;
*y = foo.y + 1;
return 0;
}
int foo_write(FOO *foop, int x, int y)
{
assert(foop == &foo);
foo.x = x + 1;
foop->y = y + 2;
return 0;
}
The library should define FOO for you, either opaquely or transparently, as it's own source refers to FOO.
#include <library.h> should get you the prototypes to the functions the library provides, and also the types needed to interact with them.
If you create your own FOO type, you'll almost certainly get a compile error indicating multiple definition of 'FOO' when you include the function prototypes from the library.
I was experimenting with C11 and VLAs, trying to declare a struct variable on the stack with only an incomplete declaration. The objective is to provide a mechanism to create a variable of some struct type without showing the internals (like the PIMPL idiom) but without the need to create the variable on the heap and return a pointer to it. Also, if the struct layout changes, I don't want to recompile every file that uses the struct.
I have managed to program the following:
private.h:
#ifndef PRIVATE_H_
#define PRIVATE_H_
typedef struct A{
int value;
}A;
#endif /* PRIVATE_H_ */
public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
typedef struct A A;
size_t A_getSizeOf(void);
void A_setValue(A * a, int value);
void A_printValue(A * a);
#endif /* PUBLIC_H_ */
implementation.c:
#include "private.h"
#include "stdio.h"
size_t A_getSizeOf(void)
{
return sizeof(A);
}
void A_setValue(A * a, int value)
{
a->value = value;
}
void A_printValue(A * a)
{
printf("%d\n", a->value);
}
main.c:
#include <stdalign.h>
#include <stddef.h>
#include "public.h"
#define createOnStack(type, variable) \
alignas(max_align_t) char variable ## _stack[type ## _getSizeOf()]; \
type * variable = (type *)&variable ## _stack
int main(int argc, char *argv[]) {
createOnStack(A, var);
A_setValue(var, 5335);
A_printValue(var);
}
I have tested this code and it seems to work. However I'm not sure if I'm overlooking something (like aliasing, alignment or something like that) that could be dangerous or unportable, or could hurt performance. Also I want to know if there are better (portable) solutions to this problem in C.
This of course violates the effective typing rules (aka strict aliasing) because the C language does not allow an object of tye char [] to be accessed through a pointer that does not have that type (or a compatible one).
You could disable strict aliasing analysis via compiler flags like -fno-strict-aliasing or attributes like
#ifdef __GNUC__
#define MAY_ALIAS __attribute__((__may_alias__))
#else
#define MAY_ALIAS
#endif
(thanks go to R.. for pointing out the latter), but even if you do not do so, in practice everything should work just fine as long as you only ever use the variable's proper name to initialize the typed pointer.
Personally, I'd simplify your declarations to something along the lines of
#define stackbuffer(NAME, SIZE) \
_Alignas (max_align_t) char NAME[SIZE]
typedef struct Foo Foo;
extern const size_t SIZEOF_FOO;
stackbuffer(buffer, SIZEOF_FOO);
Foo *foo = (void *)buffer;
The alternative would be using the non-standard alloca(), but that 'function' comes with its own set of issues.
I am considering adopting a strategy similar to the following to solve essentially the same problem. Perhaps it will be of interest despite being a year late.
I wish to prevent clients of a struct from accessing the fields directly, in order to make it easier to reason about their state and easier to write reliable design contracts. I'd also prefer to avoid allocating small structures on the heap. But I can't afford a C11 public interface - much of the joy of C is that almost any code knows how to talk to C89.
To that end, consider the adequate application code:
#include "opaque.h"
int main(void)
{
opaque on_the_stack = create_opaque(42,3.14); // constructor
print_opaque(&on_the_stack);
delete_opaque(&on_the_stack); // destructor
return 0;
}
The opaque header is fairly nasty, but not completely absurd. Providing both create and delete functions is mostly for the sake of consistency with structs where calling the destructor actually matters.
/* opaque.h */
#ifndef OPAQUE_H
#define OPAQUE_H
/* max_align_t is not reliably available in stddef, esp. in c89 */
typedef union
{
int foo;
long long _longlong;
unsigned long long _ulonglong;
double _double;
void * _voidptr;
void (*_voidfuncptr)(void);
/* I believe the above types are sufficient */
} alignment_hack;
#define sizeof_opaque 16 /* Tedious to keep up to date */
typedef struct
{
union
{
char state [sizeof_opaque];
alignment_hack hack;
} private;
} opaque;
#undef sizeof_opaque /* minimise the scope of the macro */
void print_opaque(opaque * o);
opaque create_opaque(int foo, double bar);
void delete_opaque(opaque *);
#endif
Finally an implementation, which is welcome to use C11 as it's not the interface. _Static_assert(alignof...) is particularly reassuring. Several layers of static functions are used to indicate the obvious refinement of generating the wrap/unwrap layers. Pretty much the entire mess is amenable to code gen.
#include "opaque.h"
#include <stdalign.h>
#include <stdio.h>
typedef struct
{
int foo;
double bar;
} opaque_impl;
/* Zero tolerance approach to letting the sizes drift */
_Static_assert(sizeof (opaque) == sizeof (opaque_impl), "Opaque size incorrect");
_Static_assert(alignof (opaque) == alignof (opaque_impl), "Opaque alignment incorrect");
static void print_opaque_impl(opaque_impl *o)
{
printf("Foo = %d and Bar = %g\n",o->foo,o->bar);
}
static void create_opaque_impl(opaque_impl * o, int foo, double bar)
{
o->foo = foo;
o->bar = bar;
}
static void create_opaque_hack(opaque * o, int foo, double bar)
{
opaque_impl * ptr = (opaque_impl*)o;
create_opaque_impl(ptr,foo,bar);
}
static void delete_opaque_impl(opaque_impl *o)
{
o->foo = 0;
o->bar = 0;
}
static void delete_opaque_hack(opaque * o)
{
opaque_impl * ptr = (opaque_impl*)o;
delete_opaque_impl(ptr);
}
void print_opaque(opaque * o)
{
return print_opaque_impl((opaque_impl*)o);
}
opaque create_opaque(int foo, double bar)
{
opaque tmp;
unsigned int i;
/* Useful to zero out padding */
for (i=0; i < sizeof (opaque_impl); i++)
{
tmp.private.state[i] = 0;
}
create_opaque_hack(&tmp,foo,bar);
return tmp;
}
void delete_opaque(opaque *o)
{
delete_opaque_hack(o);
}
The drawbacks I can see myself:
Changing the size define manually would be irritating
The casting should hinder optimisation (I haven't checked this yet)
This may violate strict pointer aliasing. Need to re-read the spec.
I am concerned about accidentally invoking undefined behaviour. I would also be interested in general feedback on the above, or whether it looks like a credible alternative to the inventive VLA technique in the question.
I don't even know, whether what I'm asking is something stupid or not. I am not asking you to write any code for me, but an idea to do something in a better way.
I have a struct with a large number of items like this:
typedef struct _myStruct
{
int int1;
char char1;
int int2;
:
:
int int50;
}myStruct;
I have another enumeration which has a single entry for each item in myStruct.
enum
{
eINT1,
eCHAR1,
eINT2,
:
:
eINT50
} PARAMETER_ID;
I want to write a function for each data type [say one for int, one for char, one for string etc], which return the value of a member of myStruct, when the PARAMETER_ID is given as input.
For example I need a int GetInt(PARAMETER_ID) function which return the value of int1 when eINT1 is passed as an argument. Similarly I am going to have char GetCharacter(PARAMETER_ID), float GetFloat(PARAMETER_ID) etc.
The number of items in the struct can be large. So using a switch-case for each item will not be a viable option.
Only other option I can think of is using the address of the structure variable and offsetof() function to calculate the address of the parameter and then by memcpying the required bytes into a variable. In that case I need to keep the offset of each parameter somewhere, but that is not a problem.
I am looking for alternate options to do this. Any help will be greatly appreciated.
Thank you.
A large switch is a good viable option.
You might also play preprocessor tricks.
You could have a mystruct.def file containing
INTFIELD(int1)
CHARFIELD(char1)
INTFIELD(int2)
etc... Then you would include it several times; to declare the structure:
struct _myStruct {
#define INTFIELD(F) int F;
#define CHARFIELD(F) char F;
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
};
To declare the enumeration (using e_int1 instead of eINT1)
enum field_en {
#define INTFIELD(F) e_##F,
#define CHARFIELD(F) e_##F,
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
};
To implement the accessor,
int get_int(struct _myStruct*s, enum field_en f)
{
switch (f) {
#define INTFIELD(F) case e_##F: return s->F;
#define CHARFIELD(F) /*nothing*/
#include "mystruct.def"
#undef INTFIELD
#undef CHARFIELD
default: return 0;
}}
I don't claim this is better or more readable code, but that kind of programming style does appear in some C or C++ programs (e.g. GCC internals with its gcc/tree.def)
If you code is a very large code base, and you are ready to spend days of work (e.g. because you have a lot of such struct and don't want to play such tricks) you might consider making a GCC extension with MELT (a high-level domain specific language to extend GCC) to help you; you probably can make a MELT extension to generate the accessor functions for you.
You could also convince your boss to generate both the struct, the enum and the accessor functions from an ad-hoc descriptive file (using awk, python or whatever). GCC does such tricks for its options file, e.g. gcc/common.opt
At last, if the header containing the _myStruct is so sacred that you are not allowed to touch it, and if it is very cleanly formatted, you might make an ad-hoc (e.g. awk) script to get that declaration and process it.
NB a good compiler optimizes dense switch statements as indexed jumps which take constant time, even for hundred of cases.
#include <stddef.h>
#include <stdio.h>
struct S
{
int int1;
char char1;
int int2;
char char2;
long long1;
} myStruct = {12345, 'A', 321, 'B', -1L};
enum
{
eINT1 = offsetof(struct S, int1),
eCHAR1 = offsetof(struct S, char1),
eINT2 = offsetof(struct S, int2),
eCHAR2 = offsetof(struct S, char2),
eLONG1 = offsetof(struct S, long1),
} PARAMETER_ID;
char GetChar(int para_id)
{
return *((char*)((char *)&myStruct + para_id));
}
int GetInt(int para_id)
{
return *((int*)((char *)&myStruct + para_id));
}
long GetLong(int para_id)
{
return *((long*)((char *)&myStruct + para_id));
}
void main(void)
{
printf("offsetof int1 = %d\n", eINT1);
printf("offsetof char1 = %d\n", eCHAR1);
printf("offsetof int2 = %d\n", eINT2);
printf("offsetof char2 = %d\n", eCHAR2);
printf("offsetof long1 = %d\n", eLONG1);
printf("int1 = %d\n", GetInt (eINT1));
printf("char1 = %c\n", GetChar(eCHAR1));
printf("int2 = %d\n", GetInt (eINT2));
printf("char2 = %c\n", GetChar(eCHAR2));
printf("long1 = %ld\n", GetLong(eLONG1));
}
You partially answer your own question, offsetof is meant to be used for this very purpose. You have to consider struct padding/alignment. I think you are looking for something similar to this:
#include <stddef.h> // size_t, offsetof
#include <string.h> // memcpy
#include <stdio.h>
typedef struct
{
int int1;
char char1;
int int2;
int int50;
} myStruct;
typedef enum
{
eINT1,
eCHAR1,
eINT2,
eINT50,
ITEMS_IN_STRUCT
} myEnum;
static const size_t MYSTRUCT_MEMBER_OFFSET [ITEMS_IN_STRUCT] =
{
offsetof(myStruct, int1),
offsetof(myStruct, char1),
offsetof(myStruct, int2),
offsetof(myStruct, int50),
};
static const myStruct MS;
static const size_t MYSTRUCT_MEMBER_SIZE [ITEMS_IN_STRUCT] =
{
sizeof(MS.int1),
sizeof(MS.char1),
sizeof(MS.int2),
sizeof(MS.int50)
};
void myStruct_get_member (void* result, const myStruct* ms, myEnum id)
{
memcpy (result,
(char*)ms + MYSTRUCT_MEMBER_OFFSET[id],
MYSTRUCT_MEMBER_SIZE[id]);
}
Im building a symbol table and im having a hard time writing get_symbol, which has the arguments of (symbol_table symtab, char sym). I have to write code for 2 functions get_symbol and set_symbol, I'm having some trouble understanding what a symbol table is and how to write out these two functions. it says that get_symbol() has two arguments: the symbol table, and the symbol name whose value should be retrieved. If the symbol name is one of A,B,C the corresponding value from the symbol table should be returned. if it is not one of those names, then 0 should be returned. If any one could help that would be great thanks for your time.
symbol_table.c Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "globals.h"
#include "symbol_table.h"
typedef struct symbol_table_s {
int a,b,c;
}*symbol_table_rep;
status init_symbol_table (symbol_table *p_symtab)
{
symbol_table_rep st = malloc(sizeof(struct symbol_table_s));
if (st == NULL)
return ERROR;
st->a = st->b = st->c = 0;
*p_symtab = (symbol_table) st;
return OK;
}
void destroy_symbol_table (symbol_table *p_symtab)
{
free(*p_symtab);
*p_symtab = NULL;
}
void set_symbol(symbol_table *p_symtab, char sym, int value)
{
/* WRITE CODE FOR THIS */
}
int get_symbol (symbol_table symtab, char sym)
{
/* WRITE CODE FOR THIS FUNCTION */
symbol_table_rep symtab;
if (A,B,C)
{
return symbol_table;
}else{
return 0;
}
}
symbol_table.h Code:
#ifndef _SYMBOL_TABLE_H
#define _SYMBOL_TABLE_H
#include "globals.h"
ABSTRACT_TYPE(symbol_table);
status init_symbol_table (symbol_table *p_symtab);
void destroy_symbol_table(symbol_table *p_symtab);
void set_symbol (symbol_table *p_symtab, char sym, int value);
int get_symbol (symbol_table symtab, char sym);
#endif
There are a number of other problems with your code, not least that you are passing the entire symbol table by value into get_symbol. How much of the code you're showing did you write, and how much is boiler-plate code you're supposed to leave as-is?
Here is an implementation of a symbol table where the symbols are single character and the values are just ints, as with your code. But this supports more than 3 symbols.
// symbol_table.h
struct symbol_table;
struct symbol_table* init_symbol_table(void);
void destroy_symbol_table(struct symbol_table *p_symtab);
void set_symbol (symbol_table *p_symtab, char sym, int value);
int get_symbol (const symbol_table *symtab, char sym);
// symbol_table.c
#include <limits.h>
#include <stdlib.h>
#define ARRAYSIZE(a) (sizeof(a)/sizeof((a)[0]))
struct symbol_table
{
// On rare systems, UCHAR_MAX == SIZE_MAX, and this array size will not work.
// Most people will never write code for such a system though. We'll ignore them.
int values[UCHAR_MAX+1];
};
struct symbol_table* init_symbol_table (void)
{
struct symbol_table *p = malloc(sizeof(struct symbol_table));
if (p)
{
size_t i;
for (i=0; i<ARRAYSIZE(p->values); ++i)
p->values[i] = 0;
}
return p;
}
void destroy_symbol_table(struct symbol_table *p)
{
free(p);
}
void set_symbol (symbol_table *p, char sym, int value)
{
p->values[(unsigned char)sym] = value;
}
int get_symbol (const symbol_table *p, char sym)
{
return p->values[(unsigned char)sym];
}
If you need to keep the function interface identical (complete with the rather bizarre definition of symbol_table) then you can just implement get_symbol and set_symbol with some simple conditional statements: either a sequence of if statements or a switch statement.
If you're having difficulty with that then go re-read the parts of your course materials which deal with character types and if. If your course materials don't cover that, then you should find some other resources for learning the C language; try starting with the items mentioned at Great C tutorial?
Yes, I could write the get_symbol and set_symbol code for you but I believe the help you're looking for is more around figuring out how to get started with the problem rather than a getting a finished result without understanding.
The key thing I believe you need to achieve is to get a detailed understanding of what specific actions the computer needs to take to return the value of one of the symbols. Start by stating that, as precisely as you can, in any notation at all (a diagram, or in English, whatever). Then try to implement that understanding in the C language.
This process of first understanding the mechanism by which you will solve the problem - that is, what specifically you want to make the computer do - is totally central to the process of learning to program. That learning experience is the thing this kind of homework is intended to provide, I guess. But nobody can do it for you. Showing you completed code might not help, because it won't push into your head the "Aha!" insight.
If you're really, totally, stuck, start with this implementation:
void set_symbol(symbol_table *p_symtab, char sym, int value)
{
/* WRITE CODE FOR THIS LATER */
}
int get_symbol (symbol_table symtab, char sym)
{
return 0;
}
It clearly does the wrong thing, but it will compile. Then work on it by modifying it to return a fixed value for A, for B, and for C. Then refer to your learning materials about how to access the members of a structure. Change the code to always return the value of the a member. Then try to figure out how to distinguish between the cases where the caller wants to fetch the value of A or B or C. You might find it helpful to 'artifically' set the members a b and c of the symbol table to some characteristic value to make sure you're returning the correct one (but remember to remove that code later).
Once you have done that, start working on implementing set_symbol. By the time you have made get_symbol work, set_symbol should be easy.
I have done far more C++ programming than "plain old C" programming. One thing I sorely miss when programming in plain C is type-safe generic data structures, which are provided in C++ via templates.
For sake of concreteness, consider a generic singly linked list. In C++, it is a simple matter to define your own template class, and then instantiate it for the types you need.
In C, I can think of a few ways of implementing a generic singly linked list:
Write the linked list type(s) and supporting procedures once, using void pointers to go around the type system.
Write preprocessor macros taking the necessary type names, etc, to generate a type-specific version of the data structure and supporting procedures.
Use a more sophisticated, stand-alone tool to generate the code for the types you need.
I don't like option 1, as it is subverts the type system, and would likely have worse performance than a specialized type-specific implementation. Using a uniform representation of the data structure for all types, and casting to/from void pointers, so far as I can see, necessitates an indirection that would be avoided by an implementation specialized for the element type.
Option 2 doesn't require any extra tools, but it feels somewhat clunky, and could give bad compiler errors when used improperly.
Option 3 could give better compiler error messages than option 2, as the specialized data structure code would reside in expanded form that could be opened in an editor and inspected by the programmer (as opposed to code generated by preprocessor macros). However, this option is the most heavyweight, a sort of "poor-man's templates". I have used this approach before, using a simple sed script to specialize a "templated" version of some C code.
I would like to program my future "low-level" projects in C rather than C++, but have been frightened by the thought of rewriting common data structures for each specific type.
What experience do people have with this issue? Are there good libraries of generic data structures and algorithms in C that do not go with Option 1 (i.e. casting to and from void pointers, which sacrifices type safety and adds a level of indirection)?
Option 1 is the approach taken by most C implementations of generic containers that I see. The Windows driver kit and the Linux kernel use a macro to allow links for the containers to be embedded anywhere in a structure, with the macro used to obtain the structure pointer from a pointer to the link field:
list_entry() macro in Linux
CONTAINING_RECORD() macro in Windows
Option 2 is the tack taken by BSD's tree.h and queue.h container implementation:
http://openbsd.su/src/sys/sys/queue.h
http://openbsd.su/src/sys/sys/tree.h
I don't think I'd consider either of these approaches type safe. Useful, but not type safe.
C has a different kind of beauty to it than C++, and type safety and being able to always see what everything is when tracing through code without involving casts in your debugger is typically not one of them.
C's beauty comes a lot from its lack of type safety, of working around the type system and at the raw level of bits and bytes. Because of that, there's certain things it can do more easily without fighting against the language like, say, variable-length structs, using the stack even for arrays whose sizes are determined at runtime, etc. It also tends to be a lot simpler to preserve ABI when you're working at this lower level.
So there's a different kind of aesthetic involved here as well as different challenges, and I'd recommend a shift in mindset when you work in C. To really appreciate it, I'd suggest doing things many people take for granted these days, like implementing your own memory allocator or device driver. When you're working at such a low level, you can't help but look at everything as memory layouts of bits and bytes as opposed to 'objects' with behaviors attached. Furthermore, there can come a point in such low-level bit/byte manipulation code where C becomes easier to comprehend than C++ code littered with reinterpret_casts, e.g.
As for your linked list example, I would suggest a non-intrusive version of a linked node (one that does not require storing list pointers into the element type, T, itself, allowing the linked list logic and representation to be decoupled from T itself), like so:
struct ListNode
{
struct ListNode* prev;
struct ListNode* next;
MAX_ALIGN char element[1]; // Watch out for alignment here.
// see your compiler's specific info on
// aligning data members.
};
Now we can create a list node like so:
struct ListNode* list_new_node(int element_size)
{
// Watch out for alignment here.
return malloc_max_aligned(sizeof(struct ListNode) + element_size - 1);
}
// create a list node for 'struct Foo'
void foo_init(struct Foo*);
struct ListNode* foo_node = list_new_node(sizeof(struct Foo));
foo_init(foo_node->element);
To retrieve the element from the list as T*:
T* element = list_node->element;
Since it's C, there's no type checking whatsoever when casting pointers in this way, and that will probably also give you an uneasy feeling if you're coming from a C++ background.
The tricky part here is to make sure that this member, element, is properly aligned for whatever type you want to store. When you can solve that problem as portably as you need it to be, you'll have a powerful solution for creating efficient memory layouts and allocators. Often this will have you just using max alignment for everything which might seem wasteful, but typically isn't if you are using appropriate data structures and allocators which aren't paying this overhead for numerous small elements on an individual basis.
Now this solution still involves the type casting. There's little you can do about that short of having a separate version of code of this list node and the corresponding logic to work with it for every type, T, that you want to support (short of dynamic polymorphism). However, it does not involve an additional level of indirection as you might have thought was needed, and still allocates the entire list node and element in a single allocation.
And I would recommend this simple way to achieve genericity in C in many cases. Simply replace T with a buffer that has a length matching sizeof(T) and aligned properly. If you have a reasonably portable and safe way you can generalize to ensure proper alignment, you'll have a very powerful way of working with memory in a way that often improves cache hits, reduces the frequency of heap allocations/deallocations, the amount of indirection required, build times, etc.
If you need more automation like having list_new_node automatically initialize struct Foo, I would recommend creating a general type table struct that you can pass around which contains information like how big T is, a function pointer pointing to a function to create a default instance of T, another to copy T, clone T, destroy T, a comparator, etc. In C++, you can generate this table automatically using templates and built-in language concepts like copy constructors and destructors. C requires a bit more manual effort, but you can still reduce it the boilerplate a bit with macros.
Another trick that can be useful if you go with a more macro-oriented code generation route is to cash in a prefix or suffix-based naming convention of identifiers. For example, CLONE(Type, ptr) could be defined to return Type##Clone(ptr), so CLONE(Foo, foo) could invoke FooClone(foo). This is kind of a cheat to get something akin to function overloading in C, and is useful when generating code in bulk (when CLONE is used to implement another macro) or even a bit of copying and pasting of boilerplate-type code to at least improve the uniformity of the boilerplate.
Option 1, either using void * or some union based variant is what most C programs use, and it may give you BETTER performance than the C++/macro style of having multiple implementations for different types, as it has less code duplication, and thus less icache pressure and fewer icache misses.
GLib is has a bunch of generic data structures in it, http://www.gtk.org/
CCAN has a bunch of useful snippets and such http://ccan.ozlabs.org/
Your option 1 is what most old time c programmers would go for, possibly salted with a little of 2 to cut down on the repetitive typing, and just maybe employing a few function pointers for a flavor of polymorphism.
There's a common variation to option 1 which is more efficient as it uses unions to store the values in the list nodes, ie there's no additional indirection. This has the downside that the list only accepts values of certain types and potentially wastes some memory if the types are of different sizes.
However, it's possible to get rid of the union by using flexible array member instead if you're willing to break strict aliasing. C99 example code:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ll_node
{
struct ll_node *next;
long long data[]; // use `long long` for alignment
};
extern struct ll_node *ll_unshift(
struct ll_node *head, size_t size, void *value);
extern void *ll_get(struct ll_node *head, size_t index);
#define ll_unshift_value(LIST, TYPE, ...) \
ll_unshift((LIST), sizeof (TYPE), &(TYPE){ __VA_ARGS__ })
#define ll_get_value(LIST, INDEX, TYPE) \
(*(TYPE *)ll_get((LIST), (INDEX)))
struct ll_node *ll_unshift(struct ll_node *head, size_t size, void *value)
{
struct ll_node *node = malloc(sizeof *node + size);
if(!node) assert(!"PANIC");
memcpy(node->data, value, size);
node->next = head;
return node;
}
void *ll_get(struct ll_node *head, size_t index)
{
struct ll_node *current = head;
while(current && index--)
current = current->next;
return current ? current->data : NULL;
}
int main(void)
{
struct ll_node *head = NULL;
head = ll_unshift_value(head, int, 1);
head = ll_unshift_value(head, int, 2);
head = ll_unshift_value(head, int, 3);
printf("%i\n", ll_get_value(head, 0, int));
printf("%i\n", ll_get_value(head, 1, int));
printf("%i\n", ll_get_value(head, 2, int));
return 0;
}
An old question, I know, but in case it is still of interest: I was experimenting with option 2) (pre-processor macros) today, and came up with the example I will paste below. Slightly clunky indeed, but not terrible. The code is not fully type safe, but contains sanity checks to provide a reasonable level of safety. And dealing with the compiler error messages while writing it was mild compared to what I have seen when C++ templates came into play. You are probably best starting reading this at the example use code in the "main" function.
#include <stdio.h>
#define LIST_ELEMENT(type) \
struct \
{ \
void *pvNext; \
type value; \
}
#define ASSERT_POINTER_TO_LIST_ELEMENT(type, pElement) \
do { \
(void)(&(pElement)->value == (type *)&(pElement)->value); \
(void)(sizeof(*(pElement)) == sizeof(LIST_ELEMENT(type))); \
} while(0)
#define SET_POINTER_TO_LIST_ELEMENT(type, pDest, pSource) \
do { \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pSource); \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pDest); \
void **pvDest = (void **)&(pDest); \
*pvDest = ((void *)(pSource)); \
} while(0)
#define LINK_LIST_ELEMENT(type, pDest, pSource) \
do { \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pSource); \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pDest); \
(pDest)->pvNext = ((void *)(pSource)); \
} while(0)
#define TERMINATE_LIST_AT_ELEMENT(type, pDest) \
do { \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pDest); \
(pDest)->pvNext = NULL; \
} while(0)
#define ADVANCE_POINTER_TO_LIST_ELEMENT(type, pElement) \
do { \
ASSERT_POINTER_TO_LIST_ELEMENT(type, pElement); \
void **pvElement = (void **)&(pElement); \
*pvElement = (pElement)->pvNext; \
} while(0)
typedef struct { int a; int b; } mytype;
int main(int argc, char **argv)
{
LIST_ELEMENT(mytype) el1;
LIST_ELEMENT(mytype) el2;
LIST_ELEMENT(mytype) *pEl;
el1.value.a = 1;
el1.value.b = 2;
el2.value.a = 3;
el2.value.b = 4;
LINK_LIST_ELEMENT(mytype, &el1, &el2);
TERMINATE_LIST_AT_ELEMENT(mytype, &el2);
printf("Testing.\n");
SET_POINTER_TO_LIST_ELEMENT(mytype, pEl, &el1);
if (pEl->value.a != 1)
printf("pEl->value.a != 1: %d.\n", pEl->value.a);
ADVANCE_POINTER_TO_LIST_ELEMENT(mytype, pEl);
if (pEl->value.a != 3)
printf("pEl->value.a != 3: %d.\n", pEl->value.a);
ADVANCE_POINTER_TO_LIST_ELEMENT(mytype, pEl);
if (pEl != NULL)
printf("pEl != NULL.\n");
printf("Done.\n");
return 0;
}
I use void pointers (void*) to represent generic data structures defined with structs and typedefs. Below I share my implementation of a lib which I'm working on.
With this kind of implementation, you can think of each new type, defined with typedef, like a pseudo-class. Here, this pseudo-class is the set of the source code (some_type_implementation.c) and its header file (some_type_implementation.h).
In the source code, you have to define the struct that will present the new type. Note the struct in the "node.c" source file. There I made a void pointer to the "info" atribute. This pointer may carry any type of pointer (I think), but the price you have to pay is a type identifier inside the struct (int type), and all the switchs to make the propper handle of each type defined. So, in the node.h" header file, I defined the type "Node" (just to avoid have to type struct node every time), and also I had to define the constants "EMPTY_NODE", "COMPLEX_NODE", and "MATRIX_NODE".
You can perform the compilation, by hand, with "gcc *.c -lm".
main.c Source File
#include <stdio.h>
#include <math.h>
#define PI M_PI
#include "complex.h"
#include "matrix.h"
#include "node.h"
int main()
{
//testCpx();
//testMtx();
testNode();
return 0;
}
node.c Source File
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "node.h"
#include "complex.h"
#include "matrix.h"
#define PI M_PI
struct node
{
int type;
void* info;
};
Node* newNode(int type,void* info)
{
Node* newNode = (Node*) malloc(sizeof(Node));
newNode->type = type;
if(info != NULL)
{
switch(type)
{
case COMPLEX_NODE:
newNode->info = (Complex*) info;
break;
case MATRIX_NODE:
newNode->info = (Matrix*) info;
break;
}
}
else
newNode->info = NULL;
return newNode;
}
int emptyInfoNode(Node* node)
{
return (node->info == NULL);
}
void printNode(Node* node)
{
if(emptyInfoNode(node))
{
printf("Type:%d\n",node->type);
printf("Empty info\n");
}
else
{
switch(node->type)
{
case COMPLEX_NODE:
printCpx(node->info);
break;
case MATRIX_NODE:
printMtx(node->info);
break;
}
}
}
void testNode()
{
Node *node1,*node2, *node3;
Complex *Z;
Matrix *M;
Z = mkCpx(POLAR,5,3*PI/4);
M = newMtx(3,4,PI);
node1 = newNode(COMPLEX_NODE,Z);
node2 = newNode(MATRIX_NODE,M);
node3 = newNode(EMPTY_NODE,NULL);
printNode(node1);
printNode(node2);
printNode(node3);
}
node.h Header File
#define EMPTY_NODE 0
#define COMPLEX_NODE 1
#define MATRIX_NODE 2
typedef struct node Node;
Node* newNode(int type,void* info);
int emptyInfoNode(Node* node);
void printNode(Node* node);
void testNode();
matrix.c Source File
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "matrix.h"
struct matrix
{
// Meta-information about the matrix
int rows;
int cols;
// The elements of the matrix, in the form of a vector
double** MTX;
};
Matrix* newMtx(int rows,int cols,double value)
{
register int row , col;
Matrix* M = (Matrix*)malloc(sizeof(Matrix));
M->rows = rows;
M->cols = cols;
M->MTX = (double**) malloc(rows*sizeof(double*));
for(row = 0; row < rows ; row++)
{
M->MTX[row] = (double*) malloc(cols*sizeof(double));
for(col = 0; col < cols ; col++)
M->MTX[row][col] = value;
}
return M;
}
Matrix* mkMtx(int rows,int cols,double** MTX)
{
Matrix* M;
if(MTX == NULL)
{
M = newMtx(rows,cols,0);
}
else
{
M = (Matrix*)malloc(sizeof(Matrix));
M->rows = rows;
M->cols = cols;
M->MTX = MTX;
}
return M;
}
double getElemMtx(Matrix* M , int row , int col)
{
return M->MTX[row][col];
}
void printRowMtx(double* row,int cols)
{
register int j;
for(j = 0 ; j < cols ; j++)
printf("%g ",row[j]);
}
void printMtx(Matrix* M)
{
register int row = 0, col = 0;
printf("\vSize\n");
printf("\tRows:%d\n",M->rows);
printf("\tCols:%d\n",M->cols);
printf("\n");
for(; row < M->rows ; row++)
{
printRowMtx(M->MTX[row],M->cols);
printf("\n");
}
printf("\n");
}
void testMtx()
{
Matrix* M = mkMtx(10,10,NULL);
printMtx(M);
}
matrix.h Header File
typedef struct matrix Matrix;
Matrix* newMtx(int rows,int cols,double value);
Matrix* mkMatrix(int rows,int cols,double** MTX);
void print(Matrix* M);
double getMtx(Matrix* M , int row , int col);
void printRowMtx(double* row,int cols);
void printMtx(Matrix* M);
void testMtx();
complex.c Source File
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "complex.h"
struct complex
{
int type;
double a;
double b;
};
Complex* mkCpx(int type,double a,double b)
{
/** Doc - {{{
* This function makes a new Complex number.
*
* #params:
* |-->type: Is an interger that denotes if the number is in
* | the analitic or in the polar form.
* | ANALITIC:0
* | POLAR :1
* |
* |-->a: Is the real part if type = 0 and is the radius if
* | type = 1
* |
* `-->b: Is the imaginary part if type = 0 and is the argument
* if type = 1
*
* #return:
* Returns the new Complex number initialized with the values
* passed
*}}} */
Complex* number = (Complex*)malloc(sizeof(Complex));
number->type = type;
number->a = a;
number->b = b;
return number;
}
void printCpx(Complex* number)
{
switch(number->type)
{
case ANALITIC:
printf("Re:%g | Im:%g\n",number->a,number->b);
break;
case POLAR:
printf("Radius:%g | Arg:%g\n",number->a,number->b);
break;
}
}
void testCpx()
{
Complex* Z = mkCpx(ANALITIC,3,2);
printCpx(Z);
}
complex.h Header File
#define ANALITIC 0
#define POLAR 1
typedef struct complex Complex;
Complex* mkCpx(int type,double a,double b);
void printCpx(Complex* number);
void testCpx();
I hope I hadn't missed nothing.
I am using option 2 for a couple of high performance collections, and it is extremely time-consuming working through the amount of macro logic needed to do anything truly compile-time generic and worth using. I am doing this purely for raw performance (games). An X-macros approach is used.
A painful issue that constantly comes up with Option 2 is, "Assuming some finite number of options, such as 8/16/32/64 bit keys, do I make said value a constant and define several functions each with a different element of this set of values that constant can take on, or do I just make it a member variable?" The former means a less performant instruction cache since you have a lot of repeated functions with just one or two numbers different, while the latter means you have to reference allocated variables which in the worst case means a data cache miss. Since Option 1 is purely dynamic, you will make such values member variables without even thinking about it. This truly is micro-optimisation, though.
Also bear in mind the trade-off between returning pointers vs. values: the latter is most performant when the size of the data item is less than or equal to pointer size; whereas if the data item is larger, it is most likely better to return pointers than to force a copy of a large object by returning value.
I would strongly suggest going for Option 1 in any scenario where you are not 100% certain that collection performance will be your bottleneck. Even with my use of Option 2, my collections library supplies a "quick setup" which is like Option 1, i.e. use of void * values in my list and map. This is sufficient for 90+% of circumstances.
You could check out https://github.com/clehner/ll.c
It's easy to use:
#include <stdio.h>
#include <string.h>
#include "ll.h"
int main()
{
int *numbers = NULL;
*( numbers = ll_new(numbers) ) = 100;
*( numbers = ll_new(numbers) ) = 200;
printf("num is %d\n", *numbers);
numbers = ll_next(numbers);
printf("num is %d\n", *numbers);
typedef struct _s {
char *word;
} s;
s *string = NULL;
*( string = ll_new(string) ) = (s) {"a string"};
*( string = ll_new(string) ) = (s) {"another string"};
printf("string is %s\n", string->word);
string = ll_next( string );
printf("string is %s\n", string->word);
return 0;
}
Output:
num is 200
num is 100
string is another string
string is a string