Templating in C using the Preprocessor - c

I'm wondering why I have never seen the following way to implement templates
in C before. My idea was to make the Preprocessor to the templating-work.
container.h:
#ifndef TEMPLATE_TYPE
#error "missing decalaration TEMPLATE_TYPE"
#endif
#define _CONCAT(a, b) a##b
#define _EVALUATOR(a, b) _CONCAT(a, b)
#define MAKE_NAME(a, b) _EVALUATOR(a, b)
typedef struct {
TEMPLATE_TYPE data;
} MAKE_NAME(Container_, TEMPLATE_TYPE);
main.c:
#define TEMPLATE_TYPE int
#include "container.h"
int main() {
Container_int c;
c.data = 99923;
}
So, what's the case?
This is just considered "bad style"
It's so obvious that nobody would write an article about it
There are a lot of articles, just google man!
I would appreciate comments about this technique when you are not planning
to answer with #3.

You can do incredible things (good and evil) with the preprocessor. Whether it's considered bad style or not is a judgement call, and it largely depends on the quality, readability, and maintainability of the code that results. Complicated preprocessor macros are a pain to write, debug, and maintain. However, the best C code is the code you don't write, and macros are great for automatically generating variations on a theme.
Here are some good examples of preprocessor (ab)use:
The SimpleScalar processor simulator's machine.def file (which is C code, despite the extension)
The canonical queue.h linked-list headers
The SimpleScalar code uses a pattern like your suggestion, above, where the #include is preceded by a #define that gives the header some direction.
If you're considering serious use of the preprocessor, you should look at the Boost preprocessor library. (Don't be put off by Boost's C++ roots, the preprocessor macros work fine with C.)

Instead of
typedef struct {
TEMPLATE_TYPE data;
} MAKE_NAME(Container_, TEMPLATE_TYPE)
you might want to do
#define MAKE_CONTAINER(type) typedef struct MAKE_NAME(Container_, type) { type data; } MAKE_NAME(Container_, type)
in order to be able to do
#include "container.h"
MAKE_CONTAINER(int);
MAKE_CONTAINER(double);
int main() {
Container_int c; // one way to go
struct Container_double d; // my preferred way: don't typedef when not needed; let the structs be obvious.
c.data = 99923;
d.data = 3.5;
}

Related

C conditional compilation - is there a more elegant way

I am refactoring a few c code files based on a variable set in Makefile, and I realize that there are lots of code that need conditional compilation across the files. I find that I'm doing this a lot:
#if COND1
void func1(int a1, int b1) {
Struct1 info;
#else
void func1(int a1) {
Struct2 info;
#endif
switch (info.type)
{
#if COND1
case c1:
case c2:
...
#else
case c3:
#endif
case c4:
...
}
The code soon becomes messy and ugly in my opinion.
But the portion of the code that needs conditional compilation is like 10%-20% and all the others are exactly the same, so I don't think I need extra files just to distinguish between the two versions of the code.Is there any way I can do this more elegantly? Inserting #if... everywhere in the code makes it a headache just to read. I'm quite new to C so please let me know if there's anything I need to catch up on and any advice is appreciated, thanks.
To avoid many conditional compilation directives, you could use this approach with macros:
#if COND1
#define Func1Struct Struct1
#else
#define Func1Struct Struct2
#define func1(a, b) (func1)(a)
#endif
void func1(int a1, int b1) {
Func1Struct info;
...
The advantage of defining func1 as a macro is you only have a single definition point for the function, which is better for ctags and debugging and the call sites are handled transparently too.
Platform specific case values still require explicit preprocessor directives.
This is not elegant by any means, but it does hide some of the ugliness effectively.

displaying #define values in C

I have a series of #defines from a library file header of this sort:
typedef int Lib_error;
#define LIB_ERROR_A ((Lib_error) 0x0000)
#define LIB_ERROR_D ((Lib_error) 0x0100)
#define LIB_ERROR_F ((Lib_error) 0x0200)
#define LIB_ERROR_K ((Lib_error) 0x0300)
#define LIB_ERROR_O ((Lib_error) 0x0400)
#define LIB_ERROR_P ((Lib_error) 0x0500)
#define LIB_ERROR_R ((Lib_error) 0x0600)
#define LIB_ERROR_X ((Lib_error) 0x0700)
#define LIB_ERROR_Y ((Lib_error) 0x0800)
#define LIB_ERROR_M ((Lib_error) 0x0900)
/* and so on */
Is there any way apart I can print these values so if for example
uint MyError;
/* printf("Error = %s",MyError); It should print the string LIB_ERROR_F instead of say 0x200 */
I could use lot's of if else for this but I was wondering if there was a cleverer way. Please note that I can't change the contents of library header file in anyway.
People seem to have mixed feelings about them, but X-macros are one possible solution.
But if you can't change the header, then your only two options (AFAIK) are:
Doing it manually
Some form of code generation step in your build process. In your case, it should probably be possible by parsing the header file with sed (assuming you're working on Linux).
There isn't a simple or automatic way to do it. You have to generate the list of numbers and names yourself, and provide a lookup function to map between number and name.
You might take a look at the ideas in the blog post 'Enums, Strings and Laziness'; it has some ideas that might help you. (That's closely related to the X-Macros at Dr Dobbs mentioned by Oli Charlesworth; the article there claims the technique goes back to the 60s, albeit that it must have been in a language other than C since C didn't exist back then.)
Warning: The below code piece is just a sample. It can be improvised a lot which is for you to do. : )
Define a structure like below:
typedef struct ErrorStorage
{
Lib_error err;
char err_string[100];
}ErrNoStore;
ErrNoStore arrErr[25];
arrErr[0].err = LIB_ERROR_A;
strcpy(arrErr[0].err_string, "LIB_ERROR_A");
/... and so on .../
and later down in the code define a function like this and call it
void display_error(Lib_error errnum)
{
int i = 0;
for(i=0; i<25;i++)
{
if(errnum == arrErr[i].err)
{
printf("%s\n", arrErr[i].err_string);
}
}
}
}
Just generate a table by parsing those defines in some scripting language. Should be easy-ish to translate those defines to the declaration of a constant array of code, string structs which you can then iterate.
Assuming the library doesn't change often, you'll only need to do this once so you don't need to bother much with script corectness etc.

What's the use of defining ARGS in a different header file?

So I've been going through some code, and there's some things I can't understand.
I have two header files. One is called 'args.h' and in that there are these statements, amongst others:
#if (defined(__cplusplus) || defined(__STDC__) || defined(c_plusplus))
#define NEW_STYLE 1
#define VOID void
#define ARGS(parenthesized_list) parenthesized_list
#else
#define NEW_STYLE 0
#define VOID
#define ARGS(parenthesized_list) ()
#define const
#endif
#if !defined(EXIT_SUCCESS)
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
#endif
In the other header file, function prototypes are declared like this:
#if defined(__cplusplus)
extern "C" {
#endif
extern void yyerror ARGS((const char *s_));
extern int yylex ARGS((void));
extern int yyparse ARGS((void));
extern int yywrap ARGS((void));
#if defined(__cplusplus)
}
#endif
and a bunch of other stuff.
So my questions are:
1> What exactly does #define const do?
2> Why is arg declared in the other header file? Couldn't we simply declare the functions like a normal extern void a(const char *s__)? Or is this simply a preference of style?
Thanks.
This is to allow the code to compile with a pre-standard C compiler. It turns a function prototype into a function declaration, and simply removes const completely.
If you need to use a compiler so ancient that it doesn't understand prototypes or const, you have little choice but to use something like this. Otherwise, you're generally best off eliminating these horrible kludges.
20 years ago, code like this was common and necessary. It seems harder to excuse today, but I suppose there may still be a few platforms for which a reasonably modern compiler isn't available.
That are tweaks to make the code portable among compilers lacking this or that feature
is removing const everywhere (for sure not a good idea if you have a modern compiler)
this has to do with the ANSI C Syntax

Why doesn't ANSI C have namespaces?

Having namespaces seems like no-brainer for most languages. But as far as I can tell, ANSI C doesn't support it. Why not? Any plans to include it in a future standard?
For completeness there are several ways to achieve the "benefits" you might get from namespaces, in C.
One of my favorite methods is using a structure to house a bunch of method pointers which are the interface to your library/etc..
You then use an extern instance of this structure which you initialize inside your library pointing to all your functions. This allows you to keep your names simple in your library without stepping on the clients namespace (other than the extern variable at global scope, 1 variable vs possibly hundreds of methods..)
There is some additional maintenance involved but I feel that it is minimal.
Here is an example:
/* interface.h */
struct library {
const int some_value;
void (*method1)(void);
void (*method2)(int);
/* ... */
};
extern const struct library Library;
/* end interface.h */
/* interface.c */
#include "interface.h"
void method1(void)
{
...
}
void method2(int arg)
{
...
}
const struct library Library = {
.method1 = method1,
.method2 = method2,
.some_value = 36
};
/* end interface.c */
/* client code */
#include "interface.h"
int main(void)
{
Library.method1();
Library.method2(5);
printf("%d\n", Library.some_value);
return 0;
}
/* end client code */
The use of . syntax creates a strong association over the classic Library_function(), Library_some_value method. There are some limitations however, for one you can't use macros as functions.
C does have namespaces. One for structure tags, and one for other types. Consider the following definition:
struct foo
{
int a;
};
typedef struct bar
{
int a;
} foo;
The first one has tag foo, and the later is made into type foo with a typedef. Still no name-clashing happens. This is because structure tags and types (built-in types and typedef'ed types) live in separate namespaces.
What C doesn't allow is to create new namespace by will. C was standardized before this was deemed important in a language, and adding namespaces would also threaten backwards-compatibility, because it requires name mangling to work right. I think this can be attributed due to technicalities, not philosophy.
EDIT:
JeremyP fortunately corrected me and mentioned the namespaces I missed. There are namespaces for labels and for struct/union members as well.
C has namespaces. The syntax is namespace_name. You can even nest them as in general_specific_name. And if you want to be able to access names without writing out the namespace name every time, include the relevant preprocessor macros in a header file, e.g.
#define myfunction mylib_myfunction
This is a lot cleaner than name mangling and the other atrocities certain languages commit to deliver namespaces.
Historically, C compilers don't mangle names (they do on Windows, but the mangling for the cdecl calling convention consists of only adding an underscore prefix).
This makes it easy to use C libraries from other languages (including assembler) and is one of the reasons why you often see extern "C" wrappers for C++ APIs.
just historical reasons. nobody thought of having something like a namespace at that time. Also they were really trying to keep the language simple. They may have it in the future
Not an answer, but not a comment. C doesn't provide a way to define namespace explicitly. It has variable scope. For example:
int i=10;
struct ex {
int i;
}
void foo() {
int i=0;
}
void bar() {
int i=5;
foo();
printf("my i=%d\n", i);
}
void foobar() {
foo();
bar();
printf("my i=%d\n", i);
}
You can use qualified names for variables and functions:
mylib.h
void mylib_init();
void mylib_sayhello();
The only difference from namespaces it that you cannot be using and cannot import from mylib.
ANSI C was invented before namespaces were.
Because people who want to add this capability to C have not gotten together and organized to put some pressure on compiler author teams and on ISO bodies.
C doesn't support namespaces like C++. The implementation of C++ namespaces mangle the names. The approach outlined below allows you to get the benefit of namespaces in C++ while having names that are not mangled. I realize that the nature of the question is why doesn't C support namespaces (and a trivial answer would be that it doesn't because it wasn't implemented :)). I just thought that it might help someone to see how I've implemented the functionality of templates and namespaces.
I wrote up a tutorial on how to get the advantage of namespaces and/or templates using C.
Namespaces and templates in C
Namespaces and templates in C (using Linked Lists)
For the basic namespace, one can simply prefix the namespace name as a convention.
namespace MY_OBJECT {
struct HANDLE;
HANDLE *init();
void destroy(HANDLE * & h);
void do_something(HANDLE *h, ... );
}
can be written as
struct MY_OBJECT_HANDLE;
struct MY_OBJECT_HANDLE *my_object_init();
void my_object_destroy( MY_OBJECT_HANDLE * & h );
void my_object_do_something(MY_OBJECT_HANDLE *h, ... );
A second approach that I have needed that uses the concept of namespacing and templates is to use the macro concatenation and include. For example, I can create a
template<T> T multiply<T>( T x, T y ) { return x*y }
using template files as follows
multiply-template.h
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y);
multiply-template.c
_multiply_type_ _multiply_(multiply)( _multiply_type_ x, _multiply_type_ y) {
return x*y;
}
We can now define int_multiply as follows. In this example, I'll create a int_multiply.h/.c file.
int_multiply.h
#ifndef _INT_MULTIPLY_H
#define _INT_MULTIPLY_H
#ifdef _multiply_
#undef _multiply_
#endif
#define _multiply_(NAME) int ## _ ## NAME
#ifdef _multiply_type_
#undef _multiply_type_
#endif
#define _multiply_type_ int
#include "multiply-template.h"
#endif
int_multiply.c
#include "int_multiply.h"
#include "multiply-template.c"
At the end of all of this, you will have a function and header file for.
int int_multiply( int x, int y ) { return x * y }
I created a much more detailed tutorial on the links provided which show how it works with linked lists. Hopefully this helps someone!
You can. Like other's answer, define function pointers in a struct.
However, declare it in your header file, mark it static const and initialize it with the corresponding functions.
With -O1 or higher it will be optimized as normal function calls
eg:
void myfunc(void);
static const struct {
void(*myfunc)(void);
} mylib = {
.myfunc = myfunc
};
Take advantage of the #include statement so you do not need to define all functions in one single header.
Do not add header guards as you are including it more than once.
eg:
header1.h
#ifdef LIB_FUNC_DECL
void func1(void);
#elif defined(LIB_STRUCT_DECL)
struct {
void(*func)(void);
} submodule1;
#else
.submodule1.func = func1,
#endif
mylib.h
#define LIB_FUNC_DECL
#include "header1.h"
#undef LIB_FUNC_DECL
#define LIB_STRUCT_DECL
static const struct {
#include "header1.h"
#undef LIB_STRUCT_DECL
} mylib = {
#include "header1.h"
};

I am a bit lost as to the meaning of this C preprocessor statement,

So, to start off, here's the code, with actual names switched for generic ones to limit confusion.
/* Get the list of Hotkey commands */
#define A_COMMANDS_MACRO(a, b, c, d) a = b ,
enum {
#include "commandsFile.def"
} ;
#undef A_COMMANDS_MACRO
This is a snippet from some source code I have been looking over and considering forking as a way to familiarize myself with the intricacies of the C programming language. So, to my untrained eye, this appears to do nothing. To my brain, defining something and then immediately undefining it would seem to cancel each other out.
Obviously, I realize that I'm wrong. But why am I wrong?
The "commandsFile.def" file probably uses the "A_COMMANDS_MACRO" macro somewhere internally.
Remember that "#include" essentially pastes the included file into the including one, so the #define is still in effect when "commandsFile.def" is processed.
What you see there is usually called X-MACRO. The technique consists in defining macros via #define, and then including a file that makes use of them with #include.
As a very simple example, you could have a header (say myheader.h) that declared 2 functions in the form of:
int foo(MYTYPE a, MYTYPE_PTR b);
void bar(MYTYPE a, MYTYPE_PTR b);
And then, in your code:
#define MYTYPE int
#define MYTYPE_PTR int*
#include "myheader.h"
#undef MYTYPE
#undef MYTYPE_PTR
The #undefs are sometimes in the included file as well.
For more information, take a look at this Wikipedia link.
The commandsFile.def should contain many lines:
A_COMMANDS_MACRO(A_COMMAND, 10, na, na)
A_COMMANDS_MACRO(OTHER_COMMAND, 23, na, na)
So that the code would create an enum with available commands and their codes.
It could be useful when this .def file is used by a program written in other language, so that instead of implementing text parsing, it uses C preprocessor to do this.

Resources