473,378 Members | 1,410 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Recursing macro preprocessing?

I have an application which compiles on a number of different platforms. Now
I'm trying to incorporate an external library which is only available to a
subset of the platforms that my application support.
This is ok as it will give increased usability on some platforms but not
all.

The problem however is to remove code at compiletime when my application is
compiled on a platform which does not support this library.

Using the preprocessor I can enumerate all the platforms on which this
library support like:

#if (defined(_WIN32) && defined(_M_IX86)) || \

(defined(_WIN64) && defined(_M_AMD64)) || \

(defined(__APPLE__) && defined(__ppc__)) || \

(defined(__APPLE__) && defined(__i386__)) || \

....

#endif

However in those places of my application where the support code to use the
library is defined I'd like to condtionally enable the code on a platform
where support is present.

More specifically I'd like to do:

INCLUDE_MY_LIB_SUPPORT_START

printf("This platform has library support\n");

INCLUDE_MY_LIB_SUPPORT_END

On platforms with library support it the macro would expand to nothing. On
unsupported platforms it would expand to #if 0 and #endif and thus removed
by the compiler.

The first few tests showed however that this is not easily possible. The
alternative is then something like:

#ifdef INCLUDE_MY_LIB_SUPPORT

printf("This platform has library support\n");

#endif

This is not as good however as one can easily forget to include the needed
header file and then you get no warning but code on supported platforms will
still be removed.

Is there a way to solve this? One other thing is to define it at compile
time through a switch like -DMY_LIB_SUPPORT but I'd like to keep down the
number of switches on commandline.

Thanks.

-- Henrik
Oct 21 '06 #1
4 1569
Henrik Goldman wrote:
On platforms with library support it the macro would expand to nothing. On
unsupported platforms it would expand to #if 0 and #endif and thus removed
by the compiler.
Not possible. It is not possible to produce a preprocessing directive
using preprocessing. If you produce the tokens ``#if 0'', they will not
be treated as a preprocessing directive, even though they look like
one.
The first few tests showed however that this is not easily possible. The
alternative is then something like:

#ifdef INCLUDE_MY_LIB_SUPPORT

printf("This platform has library support\n");

#endif

This is not as good however as one can easily forget to include the needed
header file and then you get no warning but code on supported platforms will
still be removed.
Use integer values, instead of testing for symbol existence:

#if INCLUDE_MY_LIB_SUPPORT
#endif

Now you either have

#define INCLUDE_MY_SUPPORT 0

or

#define INCLUDE_MY_SUPPORT 1

If you forget to define it, then the #if is ill-formed, having no
expression.

Oct 21 '06 #2
In article <11**********************@i42g2000cwa.googlegroups .com>,
Kaz Kylheku <kk******@gmail.comwrote:
#if INCLUDE_MY_LIB_SUPPORT
#endif

Now you either have

#define INCLUDE_MY_SUPPORT 0

or

#define INCLUDE_MY_SUPPORT 1

If you forget to define it, then the #if is ill-formed, having no
expression.
Fairly certain in the case above it is well formed as any ids
not replaced become replaced by a 0 token.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in beta!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Oct 22 '06 #4
Greg Comeau wrote:
In article <11**********************@i42g2000cwa.googlegroups .com>,
Kaz Kylheku <kk******@gmail.comwrote:
#if INCLUDE_MY_LIB_SUPPORT
#endif
[ snip ]
If you forget to define it, then the #if is ill-formed, having no
expression.

Fairly certain in the case above it is well formed as any ids
not replaced become replaced by a 0 token.
Ah crap, right.

Then, to defeat all this defaulting, you can to impose an enumeration.
For instance, the rule that two symbols must be defined:

#if defined INCLUDE_MY_SUPPORT
...
#elif !defined NO_INCLUDE_MY_SUPPORT
#error must explicitly request no support
#endif

The obvious alternative way to solve the original problem is to create
an API which is always defined, and always called. On the subset of the
platforms that have the special library, the API calls the library. On
the platforms where it doesn't, the API is just stubs that do the right
kind of nothing for each function.

// In the header file

#if .. test for all the platforms where library is supported ...
// #include or otherwise define the library API
int library_function();
#else
// define dummy version of the API which does nothing, using inline
functions
inline int library_function() { return 0; }
// or, using macros:
#define library_function() ((int) 0)
#endif

And so now there is no special dance to repeat in the sources, where
you simply call the function:

library_function(); // might do nothing if not supported

This also takes care of the forgotten header include.

Oct 22 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: John | last post by:
Please, consider this macro: #define mymacro(arg1, arg2) arg1 and arg2 Then it is used: mymacro(boys, girls) How is its expansion?
5
by: Hal Styli | last post by:
Hello, can someone please help with the following attempt at defining a macro ... I want to wrap the following in a macro:- if HEAD is defined then head=p; define HEAD else tail->next=p;
2
by: Gustavo L. Fabro | last post by:
Greetings. Is there a way to run the preprocessor twice? Rephrasing that, is there a way to: #define SOMETHING #pragma OTHERTHING and have the preprocessor in somecode.cpp evaluate: ...
2
by: aravindh.k | last post by:
Hi, I want to define a macro that defines another on invocation. Somthing like this: #define MACRO_NR_1(FLAG, VALUE) #define MACRO_NR_1_##FLAG(VALUE) (VALUE+FLAG) So that when I call...
7
by: fei.liu | last post by:
#define ONCFILE_ERR1(funcname, name) \ { \ #ifdef DEBUG\ cerr << __FILE__ << ":" << __LINE__ << " duplicated call to " << funcname << " " << name << endl; \ #endif \ } I want to have...
21
by: Marius Lazer | last post by:
Is it possible to write a macro that single-quotes its argument? #define SOME_MACRO(x) such that SOME_MACRO(foo) expands to 'foo' Thanks, Marius
13
by: Rick Anderson | last post by:
Group, I want to define a #include directive from another macro, if possible... For example, the following doesn't work but is basically what I need to do: #define...
11
by: lovecreatesbea... | last post by:
#define MIN(x, y) ((x)<(y) ? (x):(y)) Can a version without conditional operator of MIN macro be written?
5
by: Francois Grieu | last post by:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at #define a(b) b int main(void){return a( #if 0 #endif 0);} More generally, this compiler seems confused by any preprocessing...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.