Define a preprocessor macro with preprocessor comands - c

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

Related

Using macro statement in macro function in C

Using #ifdef <macro> <statement> #endif allows one to have verbose messages displayed only during development and is quite handy. I wonder if something like the code below is possible, becoming even shorter:
// pseudo-code:
#define IN_DEV
#define DEBUG_ONLY(statement) (#ifdef IN_DEV (statement) #endif)
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
This would only cost me a very readable one-liner which can be turned on or off. Is something like this / close to this possible?
You could change the meaning of DEBUG_ONLY dependent on if IN_DEV is defined:
// pseudo-code:
#ifdef IN_DEV
#define DEBUG_ONLY(statement) {statement}
#else
#define DEBUG_ONLY(statement) // Nothing
#endif
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
Running example: Link
It doesn't make much sense to pass whole expressions as parameters to macros. That is both dangerous and unmaintainable. Worse yet, it's taking us down the obfuscation road of "lets invent our own private macro language instead of using readable C that anyone can understand". That's a terrible idea even for debugging purposes.
The more sensible approach would be a function-like printing macro which only prints something in debug build.
#ifdef INDEV
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#else
#define DEBUG_PRINT(...)
#endif
int main(void)
{
DEBUG_PRINT("hello from debug mode\n");
}
Optionally this macro can be narrowed down to only accept strings and be made more type safe (C17 only):
#ifdef INDEV
#define DEBUG_PRINT(str) _Generic((str), char*: puts(str))
#else
#define DEBUG_PRINT(str) _Generic((str), char*: (void)0)
#endif
That is not possible. You cannot use #if inside a macro definition.
What you can do is this:
#define IN_DEV
#ifdef
#define DEBUG_ONLY(statement) (statement)
#else
#define DEBUG_ONLY(statement)
#endif
int main(void)
{
DEBUG_ONLY(printf("hello from debug mode\n");)
//...
}
This is also switchable with only a single macro IN_DEV.

How to use C constructor in windows? does the MSVC compiler provides one? [duplicate]

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

Preprocessor Directive: #elif not defined?

Is there a preprocessor directive that checks whether a constant is not defined. I am aware of the #ifndef directive but I am also looking for a #elif not defined directive. Does #elif not defined exist?
This is how I would use it:
#define REGISTER_CUSTOM_CALLBACK_FUNCTION(callbackFunctName) \
#ifndef CUSTOM_CALLBACK_1 \
#define CUSTOM_CALLBACK_1 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#elif not defined CUSTOM_CALLBACK_2 \
#define CUSTOM_CALLBACK_2 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#elif not not defined CUSTOM_CALLBACK_3 \
#define CUSTOM_CALLBACK_3 \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName) \
#endif
How about the
#elif !defined(...)
But you've got bigger problems - the trailing \ exclude the other directives - or rather make them illegal. So, even with the valid syntax, your definitions won't do what you want.
You'll need to move the initial define inside the conditions.
#ifndef CUSTOM_CALLBACK_1
#define CUSTOM_CALLBACK_1
#define REGISTER_CUSTOM_CALLBACK_FUNCTION(callbackFunctName) \
FORWARD_DECLARE_CALLBACK_FUNCTION(callbackFunctName)
#elif !defined(CUSTOM_CALLBACK_2)
//.....

How to enable custom TRACE macro for specific files only?

I wrote the following trace macro in a file named "debug.h".
#define TRACE(x) \
printf( \
"%s(%d): ", \
__FILE__, \
__LINE__ \
); \
\
printf(x);
In debug I'd like to enable the macro only for certain files since resources are limited on the platform that I'm using. I don't want to completely remove the TRACE calls from the files. Just disable them.
Is there a clean way to do this in C using the preprocessor?
In debug.h:
#if TRACE_ENABLE
#define TRACE(x) \
printf( \
"%s(%d): ", \
__FILE__, \
__LINE__ \
); \
\
printf(x);
#else
#define TRACE(x)
#endif
Then, in your source files where you don't want trace:
#define TRACE_ENABLE 0
#include "debug.h"
or just:
#include "debug.h"
In source files to enable trace:
#define TRACE_ENABLE 1
#include "debug.h"
While both answers seems good to me, I think Giuseppe's answer is more useful most of the time since if you use this macro many times in a file, and you want to switch debug on/off for complete files, pmg's method is exhausting.
The important thing is to not forget adding the else statement: #else TRACE(X); if you want to edit it in the specific file and not in header, use:
#ifdef TRACE
#undef TRACE
#endif
#define TRACE(X)
A trick I've used somtimes is the use of a bit mask to enable a subset of the files whete the TRACE is used:
File1.c:
#if TRACE_MASK & 0x01
#define TRACE(x) ...
#endif
File2.c:
#if TRACE_MASK & 0x02
#define TRACE(x) ...
#endif
...
Then you can define your TRACE_MASK macro in the preprocessing options: /DTRACE_MASK=0x03 to enable the trace on both File1.c and File2.c
The only problem is that there is a limited numner of bits... (but you can use more than one macro: TRACE_MASK1, TRACE_MASK2...)
Bye
EDIT: of course you can write tdefinition once in a file "trace.h", and just redefine the mask in each source:
File trace.h:
#if TRACE_MASK & TRACE_CURRENT
#define TRACE(x) ...
#else
#define TRACE(x) do {} while(0)
#endif
File1.c:
#define TRACE_CURRENT 0x01
#include "trace.h"
File2.c:
#define TRACE_CURRENT 0x02
#include "trace.h"
What about
#define TRACE(x, y) do if (y) {/*your prints*/} while (0)
and also
#define TRACE_ENABLE 1
or
#define TRACE_ENABLE 0
at the top of your sources.
Then replace the TRACE invocations with
TRACE(foo, TRACE_ENABLE);

__attribute__((constructor)) equivalent in VC?

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

Resources