azalsup
azalsup

Reputation: 78

get the value of a c constant

I have a .h file in which hundreds of constants are defined as macros:

#define C_CONST_NAME Value

What I need is a function that can dynamically get the value of one of these constants.

needed function header :

int getConstValue(char * constName);

Is that even possible in the C langage?

---- EDIT

Thanks for the help, That was quick :)

as i was thinking there is no miracle solution for my needs.

In fact the header file i use is generated by "SCADE : http://www.esterel-technologies.com/products/scade-suite/"

On of the solution i got from @Chris is to use some python to generate c code that does the work.

Now its to me to make some optimizations in order to find the constant name. I have more than 5000 constants O(500^2)

i'm also looking at the "X-Macros" The first time i hear of that, home it works in C because i'm not allowed to use c++.

Thanks

Upvotes: 6

Views: 358

Answers (6)

Ben Voigt
Ben Voigt

Reputation: 283684

There's no such capability built into C. However, you can use a tool such as doxygen to extract all #defines from your source code into a data structure that can be read at runtime (doxygen can store all macro definitions to XML).

Upvotes: 1

Hasturkun
Hasturkun

Reputation: 36402

You can probably do this with gperf, which generates a lookup function that uses a perfect hash function.

Create a file similar to the following and run gperf with the -t option:

struct constant { char *name; int value; };
%%
C_CONST_NAME1, 1
C_CONST_NAME2, 2

gperf will output C (or C++) code that does the lookup in constant time, returning a pointer to the key/value pair, or NULL.

If you find that your keyword set is too large for gperf, consider using cmph instead.

Upvotes: 1

Chris Eberle
Chris Eberle

Reputation: 48785

Here you go. You will need to add a line for each new constant, but it should give you an idea about how macros work:

#include <stdio.h>

#define C_TEN 10
#define C_TWENTY 20
#define C_THIRTY 30

#define IFCONST(charstar, define) if(strcmp((charstar), #define) == 0) { \
    return (define); \
}

int getConstValue(const char* constName)
{
    IFCONST(constName, C_TEN);
    IFCONST(constName, C_TWENTY);
    IFCONST(constName, C_THIRTY);

    // No match                                                                                                                                                                                                                              
    return -1;
}

int main(int argc, char **argv)
{
    printf("C_TEN is %d\n", getConstValue("C_TEN"));

    return 0;
}

I suggest you run gcc -E filename.c to see what gcc does with this code.

Upvotes: 4

Šimon T&#243;th
Šimon T&#243;th

Reputation: 36433

This is what X-Macros are used for:

https://secure.wikimedia.org/wikipedia/en/wiki/C_preprocessor#X-Macros

But if you need to map a string to a constant, you will have to search for the string in the array of string representations, which is O(n^2).

Upvotes: 1

Jonathan Grynspan
Jonathan Grynspan

Reputation: 43472

A C preprocessor macro (that is, something named by a #define statement) ceases to exist after preprocessing completes. A program has no knowledge of the names of those macros, nor any way to refer back to them.

If you tell us what task you're trying to perform, we may be able to suggest an alternate approach.

Upvotes: 3

Ned Batchelder
Ned Batchelder

Reputation: 375594

C can't do this for you. You will need to store them in a different structure, or use a preprocessor to build the hundreds of if statements you would need. Something like Cogflect could help.

Upvotes: 6

Related Questions