Conditionally defining C function macros - c

I am wondering how I can conditionally define function macros. For instance, suppose I have a function macro called SETBIT. I would like to define my own version of it should someone using my library not include a separate header file where such a macro function would have already been defined. The reason for this is portability among different compilers.
So, I know that I can do this with constants as follows:
#ifndef X
#define X 10
#endif
I would like to do something similar with a function macro
#ifndef SETBIT
#define SETBIT(port,bit) ((port) |= (1 << (bit)))
#endif
However, I don't believe this will work.

However, I don't believe this will work.
What leads you to believe that? It will work (provided that you fix the typo - it should read #ifndef SET_BIT, I suppose).

Related

How to handle calling convention when wrapping C-code in Cython? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to interface PDFium with Cython and ran into these defines/signatures:
#if defined(COMPONENT_BUILD)
#if defined(WIN32)
#if defined(FPDF_IMPLEMENTATION)
#define FPDF_EXPORT __declspec(dllexport)
#else
#define FPDF_EXPORT __declspec(dllimport)
#endif // defined(FPDF_IMPLEMENTATION)
#else
#if defined(FPDF_IMPLEMENTATION)
#define FPDF_EXPORT __attribute__((visibility("default")))
#else
#define FPDF_EXPORT
#endif // defined(FPDF_IMPLEMENTATION)
#endif // defined(WIN32)
#else
#define FPDF_EXPORT
#endif // defined(COMPONENT_BUILD)
#if defined(WIN32) && defined(FPDFSDK_EXPORTS)
#define FPDF_CALLCONV __stdcall
#else
#define FPDF_CALLCONV
#endif
FPDF_EXPORT void FPDF_CALLCONV
FPDF_InitLibraryWithConfig(const FPDF_LIBRARY_CONFIG* config);
I'm just used to the simple function declaration with
return_type function_name();
How to wrap signatures containing calling conventions in Cython?
Unfortunately, I could not find the specific macros or the function you reference here: https://github.com/PDFium/PDFium
You should probably add what specific version of your library you are using.
However, there are things in C function declarations besides return type, function name, and parameters that come from outside C it self.
One specific one, which is not part of the C standard, is the calling convention, which specifies how sending parameters and returning from function works.
Since the keywords to specify this convention are compiler specific, it makes sense to put them in a conditional macro, to make the code portable.
It may also be done to support cross-compilation for different hardware.
So FPDF_CALLCONV is most likely something like this:
#ifdef SOME_CONDITION_TO_USE_STD_CALL
#define FPDF_CALLCONV __stdcall
#endif
Another non standard option in C (and C++) programs is a directive to export a function when building a DLL on Windows.
Since this is platform specific, to make C code cross-platform, it also needs to be in a conditional macro.
So, FPDF_EXPORT is likely something like this:
#ifdef WINDOWS
#define FPDF_EXPORT __declspec(dllexport)
#else
#define FPDF_EXPORT
#endif
Note, that on other platforms this kind of "marking" does not exist, so the macro can expand to nothing, leaving the function declaration in a more familiar form.
It should also be left blank in the version of h file you include to use the library as opposed to the one used to compile the library, as you don't need this prefix to call the function.
To conclude, it is likely you can omit these two macros in your Cuthon interface, assuming the library you are using is compatible with your platform.
FPDF_EXPORT and FPDF_CALLCONV are Macros, they are defined in the file :
https://pdfium.googlesource.com/pdfium/+/master/public/fpdfview.h
They are needed here because the library is available for different systems, and different systems have different conventions for creating the library interface.
These calls are extensions to the format you are familiar with:
return_type function_name(args)
For example you can see that FPDF_CALLCONV dissapears unless you are building the library for windows.

How to #ifdef the __builtin_prefetch function

How do I keep __builtin_prefetch() in my code, but make compilers that do not have it compile successfully? (Just doing nothing where it is found).
__builtin_prefetch() is recognised by the compiler (gcc) not the preprocessor, so you won't be able to detect it using the C preprocessor.
Since an identifier with two leading underscores is reserved for use by the implementation (so any code you use which defines such an identifier has undefined behaviour) I'd do it the other way around.
#ifdef __GNUC__
#define do_prefetch(x) __builtin_prefetch(x)
#else
#define do_prefetch(x)
#endif
and then use
do_prefetch(whatever);
where needed.
That way there is no code emitted unless it is actually needed.
Since __builtin_prefetch() accepts a variable number of arguments, you might want to adapt the above to use variadic macros (C99 and later) - if you use it with different numbers of arguments in different places in your code.
It is not exactly the best solution, but it will disable __builtin_prefetch() on all other compilers other than GCC.
#ifndef __GNUC__
# define __builtin_prefetch(x)
#endif

What concept is being exhibited in this macro wrapping?

A bunch of code just got handed over to me and I got baffled by macros in the header. I could not understand what they are for:
#define WRAPPER_MACRO(symbol) symbol
#define ANOTHER_SYMBOL WRAPPER_MACRO(ANOTHER_SYMBOL)
#define PREFIXED_ANOTHER_SYMBOL WRAPPER_MACRO(PFX_ANOTHER_SYMBOL)
Why do this? What is the benefit?
Edit: This is not the actual verbatim code from my codebase but it has the same template. I just replaced macro names.
As #Michael said, we'll need to see the real macros to know for sure. But without them, I'm willing to take a few guesses that might help you out.
The macro nesting is probably a stringification thing. This bit of code is from a codebase I maintain:
// As per http://gcc.gnu.org/onlinedocs/cpp/Stringification.html:
// "If you want to stringify the result of expansion of a macro argument, you
// have to use two levels of macros."
#ifndef STRINGIFY
#define STRINGIFY(s) TOSTRING(s)
#define TOSTRING(s) #s
#endif
I'm also guessing your PREFIXED_ANOTHER_SYMBOL macro is doing something similar to this, using the # or ## preprocessor directives to prepend a certain symbol to whatever you feed the macro.

Why define a macro insted of using directly?(Please see description for what exactly i want)

I am traversing through linux kernel code. I found a macro defined as #define __async_inline __always_inline. I searched for __always_inline,I found the following statement #define __always_inline inline. My question is why they need to do like this? They can directly use inline instead of this macro's?
The code says this:
#ifdef CONFIG_HAS_DMA
#define __async_inline
#else
#define __async_inline __always_inline
#endif
It is self-explained. __async_inline will be replaced by inline if CONFIG_HAS_DMA is not defined.
This is a common way to parameterize code, to move a decision of some sort (in this case, the use of inline) to a single place, so that should that decision change (for whatever reason: different compilers, different configuration options, different architectures), there is only one single place to change.

Undef'ing a function-like macro

In the C/C++ there are 2 types of macro:
#define ABC /* usual */
und
#define FUNC(a) /*function-like*/
But how can I undefine them?
Update: So there is no difference between undefing "constant-like macro" and "function-like macro"?
#undef ABC
#undef FUNC
#undef "cancels" out a previous #define. The effect is as though you never had a previous #define for a particular identifier. Do note that #defines do not respect scope, so it's best to use them only when you need to.
Also note that it doesn't matter if one macro identifier uses the "usual" syntax while another uses a "function-like" syntax. #define ABC and #define ABC(A) both define a macro named ABC. If you have both, without #undefing one of them, the latest one "overrides" the other. (Some compilers may emit a warning if this happens.)
#undef ABC
#undef FUNC

Resources