I'm using often a syntax like
#ifdef __cplusplus
extern "C"
#endif
void myCFunc();
so I tried to make a macro to have a syntax like
CFUNC(void myCFunc());
I'm not relly sure if it's something that can be done (can preprocessor execute its freshly generate code?)
The failed idea was something like
#define CFUNC(ARGUMENT) \
#ifdef __cplusplus \
extern "C" \
#endif \
ARGUMENT;
Is there a way make a macro that generates code for the preprocessor?
Thanks
You can define two different macros depending on the context:
#ifdef __cplusplus
#define CFUNC(ARGUMENT) extern "C" ARGUMENT;
#else
#define CFUNC(ARGUMENT) ARGUMENT;
#endif
CFUNC(FOO)
However, the common way to do this is the following. It includes the braces and can be used both in definitions and declarations.
#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif
EXTERN_C
void foo(void) { ... }
EXTERN_C_END
You can inverse #define and #ifdef:
#ifdef __cplusplus
#define CFUNC(ARGUMENT) \
extern "C" \
ARGUMENT;
#else
#define CFUNC(ARGUMENT) ARGUMENT;
#endif
Hello I wanted to know if it is possible to have preprocessor language ine the argument of a function.
Something like this :
static void OnTxData(
#ifdef MODULE1
TxParams_t* params
#else
Tx2Params_t* params
#endif
)
{
...
}
Instead of hard to read:
static void OnTxData(
#ifdef MODULE1
TxParams_t* params
#else
Tx2Params_t* params
#endif
)
{
...
}
#ifdef MODULE1
#define TX_Params TxParams_t
#else
#define TX_Params Tx2Params_t
#endif
static void OnTxData( TX_Params *prams)
{
...
}
or
#ifdef MODULE1
typedef TxParams_t TX_Params
#else
typedef Tx2Params_t TX_Params
#endif
static void OnTxData( TX_Params *prams)
{
...
}
or (IMO worse)
#ifdef MODULE1
static void OnTxData( TxParams_t *prams)
#else
static void OnTxData( Tx2Params_t *prams)
#endif
{
...
}
Yes. You can use these literally anywhere (as long as they go on their own line). The preprocessor "works these out" before the rest of the compiler compiles anything.
So if MODULE1 is defined then this is the code that gets compiled:
static void OnTxData(
TxParams_t* params
)
{
...
}
and if it's not defined, then this is the code that gets compiled:
static void OnTxData(
Tx2Params_t* params
)
{
...
}
Let's say I have moduleA.c moduleB.c and moduleC.c, and modules B and C need to read variables from moduleA.h, but I want to prevent them from write these variables, only A can.
After looking for a while, the only solution I found would be to use "get" functions, but I certainly have many of those variables. Is there any faster way than creating a "get" function for each variable?
Export pointers to those variables and make them const.
//moduleA.h
extern const type* const c;
//moduleA.c
type t;
const type* const c = &t;
type* p = &t;
Module A can read the object either through t, c, or p, and can modify it through t and p, while other modules can only read it through c.
You can do this with implementing properties with C preprocessor macros.
I will start with something you presumably have now — variable access without any restrictions. peek and poke functions are provided as an example to reflect how are we reading and writing these properties.
// module_a.h
//
#ifndef __MODULE_A__H__
#define __MODULE_A__H__
void poke(void);
void *foo;
int bar;
float buzz;
#endif
// module_a.c
//
#include "module_a.h"
void poke(void) {
foo = (void*) 0xDEADBABE;
bar = 314;
buzz = 2.71828f;
}
// module_b.h
//
#ifndef __MODULE_B__H__
#define __MODULE_B__H__
void peek(void);
#endif
// module_b.c
//
#include <stdio.h>
#include "module_b.h"
#include "module_a.h"
void peek(void) {
printf("%p, %d, %f\n", foo, bar, buzz);
}
Now we are going to hide these variables from other modules by moving variable declarations inside module_a.c, and declaring them as static to change their linkage to internal. Static declarations are only visible within the translation unit they were declared in (e.g. module_a.c and everything it includes).
To allow other modules to access these variables, we would create few macros to define and declare getters for each property.
// module_a.h
//
#ifndef __MODULE_A__H__
#define __MODULE_A__H__
void poke(void);
#define DECL_PROP(T, name) \
T get_##name(void);
#define DEF_PROP(T, name) \
T get_##name(void) { \
return name; \
}
DECL_PROP(void*, foo);
DECL_PROP(int, bar);
DECL_PROP(float, buzz);
#endif
// module_a.c
//
#include "module_a.h"
static void *foo;
static int bar;
static float buzz;
DEF_PROP(void*, foo);
DEF_PROP(int, bar);
DEF_PROP(float, buzz);
void poke(void) {
foo = (void*) 0xDEADBABE;
bar = 314;
buzz = 2.71828f;
}
// module_b.c
//
#include <stdio.h>
#include "module_b.h"
#include "module_a.h"
void peek(void) {
printf("%p, %d, %f\n", get_foo(), get_bar(), get_buzz());
}
However, these macros seem to be self-repeating a lot — we have mentioned each of properties three times — twice in the implementation and once in the interface part. Maintaining such construct is very error prone, so let's try to reduce this number by combining getter definition and variable declaration.
// module_a.h
//
#ifndef __MODULE_A__H__
#define __MODULE_A__H__
void poke(void);
#define DECL_PROP(T, name) \
T get_##name(void);
#define DEF_PROP(T, name) \
static T name; \
\
T get_##name(void) { \
return name; \
}
DECL_PROP(void*, foo);
DECL_PROP(int, bar);
DECL_PROP(float, buzz);
#endif
// module_a.c
//
#include "module_a.h"
DEF_PROP(void*, foo);
DEF_PROP(int, bar);
DEF_PROP(float, buzz);
void poke(void) {
foo = (void*) 0xDEADBABE;
bar = 314;
buzz = 2.71828f;
}
Now let's reduce this further by combining property definition and declaration together and moving our property macros to separate file to keep module files clean and beautiful.
// props.h
//
#ifndef __PROPS__H__
#define __PROPS__H__
#define _DECL_PROP(T, name) \
T get_##name(void);
#define _DEF_PROP(T, name) \
static T name; \
\
T get_##name(void) { \
return name; \
}
#define DECL_PROPS(PROPSET) \
PROPSET(_DECL_PROP)
#define DEF_PROPS(PROPSET) \
PROPSET(_DEF_PROP)
#endif
// module_a.h
//
#ifndef __MODULE_A__H__
#define __MODULE_A__H__
#include "props.h"
void poke(void);
#define I_WANT_MY_PROPS(_) \
_(void*, foo); \
_(int, bar); \
_(float, buzz);
DECL_PROPS(I_WANT_MY_PROPS)
#endif
// module_a.c
//
#include "module_a.h"
DEF_PROPS(I_WANT_MY_PROPS)
void poke(void) {
foo = (void*) 0xDEADBABE;
bar = 314;
buzz = 2.71828f;
}
Now, as a final touch, let's add private setters for these properties and obfuscate names of underlying variables so they would not be accessible directly.
// props.h
//
#ifndef __PROPS__H__
#define __PROPS__H__
#define _PROP_VAR_NAME(name) \
_private_property_prefix_##name
#define _DECL_PROP(T, name) \
T get_##name(void);
#define _DEF_PROP(T, name) \
static T _PROP_VAR_NAME(name); \
\
T get_##name(void) { \
return _PROP_VAR_NAME(name); \
} \
\
static inline T set_##name(T value) { \
_PROP_VAR_NAME(name) = value; \
\
return value; \
}
#define DECL_PROPS(PROPSET) \
PROPSET(_DECL_PROP)
#define DEF_PROPS(PROPSET) \
PROPSET(_DEF_PROP)
#endif
// module_a.c
//
#include "module_a.h"
DEF_PROPS(I_WANT_MY_PROPS)
void poke(void) {
set_foo((void*) 0xDEADBABE);
set_bar(314);
set_buzz(2.71828f);
}
There are many schemes you could use. However, the simplest is allow read/write access from everywhere.
To enforce that only writes can occur in moduleA, look at all the code: make sure that only moduleA is writing and all other modules either don't access it, or only read from the variable.
If you have code like
int var1;
char * var2;
// ...
double var20;
where all these varX are global variables, then you really should start refactoring them away.
One possible (although almost equally "dirty") approach is to combine them in some configuration structure and to only provide a "get" function for this structure.
Of course, if you're only concerned about the time / code it takes to create a get function, well, then I welcome you to the evil magic of the preprocessor:
#define DECLARE_GLOBAL(type, name) \
extern type name; \
type get_ ## name(void);
#define DEFINE_GLOBAL(type, name, initial) \
type name = initial; \
type get_ ## name(void) { return name; }
In your header:
DECLARE_GLOBAL(int, var1);
In your implementation file:
DEFINE_GLOBAL(int, var1, 42);
Try this at home, but don't consider it as good practice.
How can a bool function be added in a header? I've tried this so far and doesn't work
#ifndef FUNCTION_H_
#define FUNCTION_H_
BOOL MyFunction();
#endif
#ifndef FUNCTION_H_
#define FUNCTION_H_
BOOL MyFunction();
#endif
will, as you have found out, not compile.
Instead use:
#ifndef FUNCTION_H_
#define FUNCTION_H_
#include <stdbool.h>
bool MyFunction( void );
#endif
I was wondering if it's possible to use C constructors in VC just as it is possible to use them in GCC.
The gcc way is quite straight using the __attribute__ keyword, unfortunately VC doesn't seem to even know this keyword, as I'm not a Win32 programmer I wonder if there's some sort of equivalent keyword for such things.
Just to note - this is a C program, not a C++ or C# even, (as 'twas quite easy to do that in those languages)
Below C code demonstrates how to define a void(void) function to be called at program/library load time, before main executes.
For MSVC, this places a pointer to the function in the user initializer section (.CRT$XCU), basically the same thing the compiler does for the constructor calls for static C++ objects. For GCC, uses a constructor attribute.
// Initializer/finalizer sample for MSVC and GCC/Clang.
// 2010-2016 Joe Lowe. Released into the public domain.
#include <stdio.h>
#include <stdlib.h>
#ifdef __cplusplus
#define INITIALIZER(f) \
static void f(void); \
struct f##_t_ { f##_t_(void) { f(); } }; static f##_t_ f##_; \
static void f(void)
#elif defined(_MSC_VER)
#pragma section(".CRT$XCU",read)
#define INITIALIZER2_(f,p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" p #f "_")) \
static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f,"")
#else
#define INITIALIZER(f) INITIALIZER2_(f,"_")
#endif
#else
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif
static void finalize(void)
{
printf( "finalize\n");
}
INITIALIZER( initialize)
{
printf( "initialize\n");
atexit( finalize);
}
int main( int argc, char** argv)
{
printf( "main\n");
return 0;
}
You are probably interested in DllMain.
I don't think there's a way to avoid using C++ features with MSVC. (MSVC's C support sucks anyways.)
Untested, but this should at least allow the same code to work in both MSVC and GCC.
#if defined(_MSC_VER)
struct construct { construct(void (*f)(void)) { f(); } };
#define constructor(fn) \
void fn(void); static constructor constructor_##fn(fn)
#elif defined(__GNUC__)
#define constructor(fn)
void fn(void) __attribute__((constructor))
#endif
static constructor(foo);
void foo() {
...
}
I tried the last answer in MSVC like
#ifdef _MSC_VER
#pragma section(".CRT$XCU",read)
#define INITIALIZER2_(f,p) \
static void f(void); \
__declspec(allocate(".CRT$XCU")) void (*f##_)(void) = f; \
__pragma(comment(linker,"/include:" p #f "_")) \
static void f(void)
#ifdef _WIN64
#define INITIALIZER(f) INITIALIZER2_(f,"")
#else
#define INITIALIZER(f) INITIALIZER2_(f,"_")
#endif
#else
#define INITIALIZER(f) \
static void f(void) __attribute__((constructor)); \
static void f(void)
#endif
but INITIALIZER(f) can't appear in 2 different files with the same function name passed to INITIALIZER, the following definition will allow that
#ifdef _MSC_VER
#define INITIALIZER(f) \
static void f();\
static int __f1(){f();return 0;}\
__pragma(data_seg(".CRT$XIU"))\
static int(*__f2) () = __f1;\
__pragma(data_seg())\
static void f()
#else
#define INITIALIZER(f) \
__attribute__((constructor)) static void f()
#endif