Related
Let's assume that I declared a C struct for holding configuration information, which has lots of fields(~30), e.g.:
struct config {
int a;
int b;
int c;
...
char *str1;
char *str2;
...
};
What is the best way to compare two structs without simply enumerating and comparing each element?
Of course I could use the following code but my question is, is there an easier way to achieve this?
static int
cmpInstances(struct config *l, struct config *r) {
return (
l->a == r->a &&
l->b == r->b &&
l->c == r->c &&
!strcmp(l->str1, r->str1) &&
!strcmp(l->str2, r->str2)
);
}
Is there some macro that could do that? For example:
cmpInstancesViaMacro(a,b,c) would expand into
l->a == r->a &&
l->b == r->b &&
l->c == r->c
A generalized variant of so-called X Macros could be used.
In the example of the question, it would look like this:
#define CONFIG_FIELDS \
X_INT(a) \
X_INT(b) \
X_INT(c) \
X_STRING(str1) \
X_STRING(str2)
struct config {
#define X_INT(NAME) int NAME;
#define X_STRING(NAME) char *NAME;
CONFIG_FIELDS
#undef X_INT
#undef X_STRING
};
static int cmpInstances(struct config *l, struct config *r) {
#define X_INT(NAME) l->NAME == r->NAME &&
#define X_STRING(NAME) strcmp(l->NAME, r->NAME) == 0 &&
return CONFIG_FIELDS 1;
#undef X_INT
#undef X_STRING
}
With this solution, only the CONFIG_FIELDS macro needs to be changed when the structure is changed as long as there is no change to the set of types used. The structure and function would automatically be kept synchronized.
If a new type is introduced, the corresponding X Macros must be defined similar to X_INT and X_STRING above.
Perhaps some macros will help us reduce the lines of code and effort needed:
#define CMP(name) l->name == r->name &&
#define SCMP(name) !strcmp(l->name, r->name) &&
struct config
{
int a;
int b;
int c;
char *str1;
char *str2;
};
static int cmpInstances(struct config *l, struct config *r)
{
return CMP(a) CMP(b) CMP(c) SCMP(str1) SCMP(str2) 1;
}
#undef CMP
#undef SCMP
Here we define some macros that take only the name of the variable and compare them. One is written for integer comparison (CMP) and the other is written for string comparison (SCMP). Then you can use these macros to compare your data and undef them when you are done.
Thanks to chqrlie for adding 1 part.
What is the best way to compare two structs without simply enumerating and comparing each element?
The presented way is the best. Except, the pointers should point to const - nothing is getting modified.
is there an easier way to achieve this?
The presented way is the easiest way to achieve it, it's also the most readable and self-explanatory, easy to refactor and reason about. Any other will add to complexity and result in maintenance burden.
I find strcmp(...) == 0 clearer then !strcmp(...).
If you're the author of the struct, you can lay it out so there's no padding, _Static_assert that there's no padding (sizeof(whole+struct) == sum of component sizes) and then simply use one memcmp call if all the data is in the struct.
If the struct has string pointers (and you can't guarantee that a string with particular contents is stored only in one place), you'll need to do those separately.
You'll get the tightest code if you put all of them next to each other, union-them with a corresponding char*[] array, and then loop over the corresponding arrays calling strcmp on each pair and combine the result (if all were equal) with memcpy for the rest.
Something like:
#include <string.h>
struct config {
int m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,m11,m12,m13,m14,m15,m16;
union {
struct { char *s1,*s2,*s3,*s4,*s5,*s6,*s7,*s8; };
char *strings[8];
};
};
_Static_assert(sizeof(struct config) == sizeof(int)*16+sizeof(char*)*8,"");
int strings_equal(char *const A[], char *const B[], size_t Count){
for(;Count;Count--) if(0!=strcmp(*A++,*B++)) return 0;
return 1;
}
int configs_equal(struct config const *A, struct config const *B){
return 0==memcmp(A,B,sizeof(int)*16)
&& strings_equal(A->strings,B->strings,sizeof(A->strings)/sizeof(A->strings[0]));
}
I'm a little new to C still, so bear with me.
I am attempting to be able to refer to the elements of a structure via an index. I figured a macro would do the trick, but evidently not. Can anyone explain why the following does not work?
#include <stdio.h>
#define E(Structure, Index) Structure.var_Index
typedef struct test{
int var_0;
}TEST;
int main(){
TEST Test;
E(Test, 0) = 0;
return(0);
}
My IDE says "No member named 'var_Index' in 'struct test'," but I have no # in front of the word Index in the macro.
Merging tokens is done with ##
The following change should work:
#define E(Structure, Index) Structure.var_##Index
var_Index is one token and the compiler (preprocessor) won't see as Index.
You can use ## operator to have it concatenate tokens in macros.
#include <stdio.h>
#define E(Structure, Index) Structure.var_##Index
typedef struct test{
int var_0;
}TEST;
int main(){
TEST Test;
E(Test, 0) = 0;
return(0);
}
I'm trying to write a macro in C (alas, not C++) in a way to trap certain errors, in particular if I pass a name of the wrong type.
For example, with
typedef int APLNELM;
typedef int APLRANK;
#define IsScalar(a) ((a) == 0)
APLNELM AplNelm = 0;
APLRANK AplRank = 0;
Calling IsScalar (AplRank) is correct because Scalar is a Rank concept, but IsScalar (AplNelm) is wrong because Scalar is not a # elements concept.
Can some clever person find a way to write the IsScalar macro such that it checks the type of the name passed to it to ensure that it is of type APLRANK? Feel free to rewrite the original example in any equivalent way if that provides a solution.
If these are the only two types that will ever be passed into the isScalar macro, then you could do something like this:
#include <stdio.h>
struct APLNELM {
int nelm;
char a[1];
};
struct APLRANK {
int rank;
char a[2];
};
#define isScalar(b) (sizeof b.a == 2)
int main(void) {
// your code goes here
struct APLNELM temp1;
struct APLRANK temp2;
printf("%d\n", isScalar(temp1));
printf("%d\n", isScalar(temp2));
return 0;
}
The output of this code is
0
1
This will work, but I highly suggest you don't use it as it wouldn't be super maintainable:
typedef int APLNELM;
typedef int APLRANK;
typedef unsigned int TYPETRAITS;
#define TRAIT_SCALAR 0x1
#define TYPETRAITS_APLNELM TRAIT_SCALAR /*whatever else you want, up to 32 traits*/
#define TYPETRAITS_APLRANK 0/*whatever else you want, up to 32 traits*/
#define GET_TYPE_TRAITS(X) TYPETRAITS_##X
#define IS_SCALAR(X) (X & TRAIT_SCALAR)
#define IS_TYPE_SCALAR(X) IS_SCALAR(GET_TYPE_TRAITS(X))
int main()
{
const int aplnelm_traints = GET_TYPE_TRAITS(APLNELM);
const int aplrang_traints = GET_TYPE_TRAITS(APLRANK);
const bool is_aplnelm_scalar = IS_TYPE_SCALAR(APLNELM);
const bool is_aplrang_scalar = IS_TYPE_SCALAR(APLNELM);
}
I gived up with following code (requires GNU extensions: typeof and Statement Exprs):
#include <stdio.h>
typedef int APLNELM;
typedef int APLRANK;
#define IsScalar(a) \
({ \
/* Override typedefs in block scope */ \
typedef char APLNELM; \
typedef int APLRANK; \
/* Create variable with typeof(a) type; \
* then compare it by sizeof with APLNELM */ \
typeof(a) b; sizeof b == sizeof(APLNELM); \
})
int main(void)
{
APLNELM a = 5;
APLRANK b = 5;
printf("IsScalar: %d\n", IsScalar(a) ? 1 : 0);
printf("IsScalar: %d\n", IsScalar(b) ? 1 : 0);
return 0;
}
The thing is that typeof(a) is actually not replaced by APLNELM or APLRANK. C is not dynamic language, I agree that struct concept would be better suited for such differentiation.
If you want to define two integer types that are different, the straight typedef approach fails, because typedef creates synonyms for the same type, never creates new types.
There is a manner to create different integer types, but even in this case, there is no way to "detect" them through their values.
For example, observe this code:
enum myint1_e {min1 = -32767, max1 = 32767};
enum myint2_e {min2 = -32767, max2 = 32767};
typedef enum myint1_e integer1_t;
typedef enum myint2_e integer2_t;
integer1_t x1 = 0;
integer2_t x2 = 0;
Now, the two types enum myint1_t and enum myint2_t are different integer types.
See C11: 6.7.2.3.(par.5):
Two declarations of [...] enumerated types which are in different scopes or use different tags declare distinct types.
So, their typedef-ed versions are, too, different.
Thus, the variables x1 and x2 have different types.
The integer value 0 can be assigned to both variables.
Now, if you want to check that the type of a variable is the one that you want, you can try doing that:
#define VERIFY_INT1TYPE(a) ((integer1_t*)(0) == (&a))
But this method only offers a Warning message, and not the "comparisson with value false" that you expected.
Explanation: Although the integer types are, in some way, interchangeable in assignment operations, on the other hand their "pointer to" versions are always different types. Thus, a sentence like x1 == x2 has not any problem at all, but the comparisson of a value of two different pointer types will raise a warning message.
Remark: The expression (integer1_t*)(0) is the NULL pointer cast to type integer1_t*.
Example:
VERIFY_INT1TYPE(x2);
This example raise a warning message when I compiled with GCC.
One possibility is to wrap the integer in a one-field struct, to enforce strong typing. To avoid the final production code being suboptimal, compile twice with different macro definitions; once with structs to detect errors, once without structs for optimal code.
#ifdef STRONG_TYPING
#define TYPE(basetype, field) struct { basetype field; }
#define INITIALIZER(value) {(value)}
#define AS_BASETYPE(field, value) ((value).field)
#else
#define TYPE(basetype, field) basetype
#define INITIALIZER(value) (value)
#define AS_BASETYPE(field, value) (value)
#endif
typedef TYPE(int, alpnelm) APLNELM;
typedef TYPE(int, alprank) APLRANK;
#define IsScalar(a) (AS_BASETYPE(aplrank, a) == 0)
With STRONG_TYPING defined, IsScalar(SomeAplNelm) will give a compiler error. Without STRONG_TYPING, the overhead of structs will be completely gone. Naturally, all modules must to be compiled with the same definition before linking, or your executable is likely to crash.
In your program code, you will have to apply some discipline when it comes to using the macros. Declaration example:
APLNELM MyAplNelm1;
APLNELM MyAplNelm2 = INITIALIZER(0);
Assignment:
AS_BASETYPE(aplnelm, MyAplNelm1) = 0;
AS_BASETYPE(aplnelm, MyAplNelm2) = AS_BASETYPE(aplnelm, MyAplNelm1);
It is still allowed to exchange values between different 'strong' types; as long as you specify the correct type (name of the field in the struct) for each individual value.
AS_BASETYPE(aplnelm, MyAplNelm2) = AS_BASETYPE(aplrank, MyAplRank);
Please note you always need AS_BASETYPE to access a variable of one of the 'strong' types. This will make the code more verbose (please feel free to choose a shorter name for the macro), but there's nothing wrong with that. It's just a notion of metadata you are adding; it should actually improve maintainability.
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]);
}
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)