1

I want to declare data type of a variable depending on a condition in C. Is it possible?

I have written a program to implement stack using integer array, and I want the same code to implement stack of characters which is nothing but replacing some "int"s by "char"s, So how to do that??

I trid something like,

if(x == 1)
#define DATATYPE int
else
#define DATATYPE char

and many other things too but nothing worked.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
nikhil
  • 45
  • 1
  • 5
  • 1
    You can do this kind of thing elegantly in C++ with templates, but for C your only option really is ugly hacks using preprocessor macros. Check out C11's `_Generic` capability though: https://en.wikipedia.org/wiki/C11_(C_standard_revision). – Paul R Sep 25 '14 at 10:27
  • You _tried_ that? You should know that the preprocessor acts performing text substitution before the compiler kicks in. – Daniel Daranas Sep 25 '14 at 10:27

4 Answers4

5

Your code could work with #if x==1 ... #endif if x is a preprocessor symbol, e.g. if you compile with -Dx=1 command-line option to gcc ; please understand that the C preprocessor is the first phase of a C compiler, which in fact sees preprocessed code (use e.g. gcc -C -E source.c > source.i to get into source.i the preprocessed form of source.c)

In general, you could implement such generic containers using huge preprocessor macros. See e.g. sglib and this question. Or you could generate your C code with some specialized source code generator (perhaps using another preprocessor like m4 or gpp, or crafting your own generator in some scripting language).

Alternatively, use a lot of void* pointers, and pass the size of data to your routines, like qsort(3) does. See e.g. Glib containers

You might be interested in learning C++11 or Ocaml (or even Common Lisp). They offer a standard library with several generic containers (in C++ with templates in the library, in Ocaml with functors in it); read also about generic programming

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks..I think the "sglib" will be useful..At the same time, playing with void* pointers is a bit challenging and worth considering..:)..Thanks for other references you have shared – nikhil Sep 25 '14 at 14:56
  • What does "if you compile with -Dx=1" actually mean..I didnt get that – nikhil Sep 25 '14 at 15:07
  • Added a link. It is a command-line flag to `gcc` and every other command line compiler I know (`clang`, `tcc`, `nwcc` ...) – Basile Starynkevitch Sep 25 '14 at 15:11
2

You probably have a design flaw. You should really ask yourself why you want to threat C as a dynamic language like Python. C is a statically language typed, so types are fixed.

Claudio
  • 10,614
  • 4
  • 31
  • 71
1

Use this solution which encourage you to redesign by creating a struct for each value in the stack tagged_t,and then fill the data, I hope you get the idea.

    typedef union {
int i;
char c;
float f;
} evil;

typedef struct {
  evil value;
  int type;
} tagged_t;

enum {
  TYPE_INT, TYPE_CHAR, TYPE_FLOAT
};

tagged_t bar;
bar.value.c = 'a';
bar.type = TYPE_CHAR;

See the answer of Yann Ramin

Community
  • 1
  • 1
TiyebM
  • 2,684
  • 3
  • 40
  • 66
0

Firstly, please learn about the pre-processor. Now, on to your question.

This does not work, due to the fact that the compiler only actually sees:

if(x == 1)
else

The # indicates that the instruction will be executed by the pre-processor. The pre-processor is really a glorified find-and-replace when we talk about the #define command. eg:

#define PI_5_DIGITS 3.14159f

The pre-processor will find all occurrences of the tag PI_5_DIGITS and replace it with 3.14159.

Should you want to use this, make x a pre-processor symbol, by adding the switch e.g. -Dx=1.

Your code would then need to be changed to:

#ifdef x
   #define DATATYPE int
#else
  #define DATATYPE char
#endif

Suggested reading:

http://www.phanderson.com/C/preprocess.html http://gcc.gnu.org/onlinedocs/cpp

Sarima
  • 749
  • 7
  • 21