2

How can I test which identifier is passed as the value of a macro parameter in C at compile time?

I'm writing wrapper macros for a micro-controller in C (GNU).

I have some macros that work like this:

#define _ReadBits(port, mask)      (PORT ## port) & (mask)
#define ReadBits(portmask)         _ReadBits(portmask) 
#define SWITCH D, (1<<7)

This way I can say:

foo = ReadBits(SWITCH);

and I'll get

foo = PORTD & (1<<7);

That works great. I want to expand these to do something like this:

#define _ConfigAnalog(port, mask)  BUILD_BUG_ON(port != B); AD1PCFGCLR = (mask)
#define ConfigAnalog(portmask)    _ConfigAnalog(portmask)

That is, I want a compile-time error to happen if parameter port isn't B (because this micro-controller can configure only port B as analog).

Is there some way to do this in C?

2 Answers 2

4

Figured it out myself:

#define PORT_B_SUPPORTS_ANALOG

#define __CheckPort(p)  PORT_##p##_SUPPORTS_ANALOG
#define __ConfigAnalogBits(mask) AD1PCFGCLR = (mask)

#define _ConfigAnalogBits(port, mask)  __CheckPort(port); __ConfigAnalogBits(mask)
#define ConfigAnalogBits(portmask)     _ConfigAnalogBits(portmask)

#define NO_GOOD C, (1<<3)
#define VOLTAGE B, (1<<3)

void tryit(void)
{
    ConfigAnalogBits(VOLTAGE);
    //ConfigAnalogBits(NO_GOOD);
}

If "port" is B then _CheckPort compiles into a null statement.

If "port" is anything else, a build error happens.

Sign up to request clarification or add additional context in comments.

5 Comments

Avoid using identifiers that start with an underscore followed by either another underscore or an uppercase letter (e.g. avoid __this and _This) because such identifiers are reserved for the implementation.
@dreamlax: Thanks; will fix.
This does not test any "string value" of a macro parameter. It tests an identifier name. Should the downvote in my answer be yours, I'd think it fair to reconsider if your question (which I cite) is maybe not stated as clearly as it could.
@Jens: Whether the first line uses "string" instead of "identifier" - which is an understandable colloquialism/mistake in my opinion - the rest of the question made it perfectly clear what he meant.
@Jens I edited the question to remove the confusing reference to "string value"
0

How can I test the string value of a macro parameter in C at compile?

You can't.

According to C99 6.10.1 Conditional inclusion, pre-processor conditions must be an integer constant expressions, and may test whether a macro is defined (using #if, #ifdef identifier or #if defined(identifier)).

3 Comments

I think the C preprocessor is Turing complete. So you always can; the question is just how.
@nerdfever.com Turing completeness has nothing to do with arbitrary input data manipulation. A language can be Turing complete over moonbeams. That doesn't mean it can make decisions about strings.
@Gene: If you can encode strings in moonbeams, then I think you can made decisions about strings. (In principle anyway; not saying it's practical.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.