In my program I've a lot of variables which names consist of: word+number.
For example if I rand() number 6 - I have to iterate word6.
I tried to make a define function to make it easier for me, but I don't know how to parse the value of an argument.
#define it(c,t) c ## t
*in main:*
int c1=0 ,t=1;
it(c , t)++;
cout<<c1;
Can you tell me how to make it work please?
You probably don't want to do this. Consider using an array:
int word[6]; // Declares 6 int variables
word[0] = 1; // Access them with an index, 0 is the first one
word[5] = 42; // Access the last one.
This uses less characters and is how others will expect you to do this. This is probably what you want.
Related
I was wondering if there is a way to shortcut this:
int main(){
int number1,number2,number3,number4,number5,number6;
number1=0;
number2=0;
number3=0;
number4=0;
number5=0;
number6=0;
}
If variable names were strings I would do something like this:
int main(){
int number1,number2,number3,number4,number5,number6;
string number="number";
for(int i=1;i<7;i++){
number<<i=0;
}
}
Not sure though if I can use "<<" here but I think you get the point. It would be a "+" in C#.
This is just an example. But there are some points that I want to shortcut this. Thank you for your attention.
Don't think in terms of variables with related names, think in terms of data structures, where in this case you mean array:
std::vector<int> number(6, 0);
Where that creates an array with 6 entries, each containing 0.
You can use these like:
number[i]
Where i is just an index between 0 and 5.
For Legacy reasons I need to maintain the old array structure(s), however the compiler tells me that there is a problem with my 'expression syntax'.
Here's what I have:
#define Array[GlobalIndexVariable] Get(GlobalIndexVariable)->SubType;
Get returns a valid pointer to a struct, which contains SubType
Now I imagined this to take every occasion of Array[GlobalIndexVariable] and simply convert it to the function call, but apparently I was mistaken.
I don't even really know what to search for in this context, so a little help would be highly appreciated.
Thank you very much.
Edit:
Since it was asked, here is one of the lines that throw the error:
LocalVariable = Array[GlobalIndexVariable];
I wish to stress, that I'm not looking to make this into a macro, but much rather just want to replace Array[GlobalIndexVariable]; with Get(GlobalIndexVariable), so as soon as anything other than GlobalIndexVariable is used, the replacement would fail and throw a different error.
Edit:
Just to make absolutely sure that I am understood:
Right now I have 4 long arrays of type int. I want to stuff these into a struct to both mark that they belong together (they describe different aspects of the same thing) however I need a bulk solution for the previous code fragments (a few thousand occurrences).
Old:
int Index = 2;
int Array1[ANZ] = { 0, 1, 2 };
int Array2[ANZ] = { 0, 1, 2 };
int Array3[ANZ] = { 0, 1, 2 };
int Array4[ANZ] = { 0, 1, 2 };
if(Array1[Index] == 2) //doSomething
New:
struct {
int Type, Conf, Foo, Bar;
};
if(Array1[Index] == 2) //doSomething
Without touching Array1[Index] == 2, is it possible to use a define or something else to get the exact same behavior as before for the old code?
With a custom type, you may do
struct MyType
{
int& operator[](int index) const { return Get(GlobalIndexVariable)->SubType; }
};
#define Array MyType{}
And then
Array[GlobalIndexVariable]
will be replaced by
MyType{}[GlobalIndexVariable]
which will calls
Get(GlobalIndexVariable)->SubType;
Your problem is in your #define
#define Array[GlobalIndexVariable] Get(GlobalIndexVariable)->SubType;
The [] isn't a valid syntax for macro calls. If you're doing C++ you can write an operator[] for your array type. If you're in C your in a bit of a bind. You'll probably have to replace everything with round brackets rather than square ones.
I'd perform a substitution, writing something like
#ifdef USE_OLD_SYNTAX
# define GET_ARRAY_VALUE(globalIndex) Array[globalIndex]
#else
# define GET_ARRAY_VALUE(globalIndex) Get(globalIndex)->SubType;
#endif
Then use GET_ARRAY_VALUE in your code and check with USE_OLD_SINTAX which definition you want to use by find-and-replace your previous code.
But maybe it can be more simple a find-and-replace inside your code without macro at all.
(Apologies for the long title, but I couldn't think of a less specific one which would be clear enough)
I need to pass the name of an (object-like) macro to a nested (function-like) macro, as in the following (trivial) example:
#define ROOT_FUNC(INPUT) int v_ ## INPUT = INPUT
#define CALLER_FUNC(INPUT) ROOT_FUNC(INPUT)
#define INTA 1
#define INTB 2
#define INTC 3
Now, if I write ROOT_FUNC(INTA); in my code I get an integer variable called v_INTA with the value 1. If I define a variable in code, int INTD = 4;, and then write CALLER_FUNC(INTD); I end up with an integer variable called v_INTD with the value 4.
But if I write CALLER_FUNC(INTA); I get an integer variable called v_1 with a value of 1, because INTA is expanded to 1 at the time CALLER_FUNC is expanded, before ROOT_FUNC is expanded (i.e. ROOT_FUNC(1) is what gets expanded).
If I change line 2 to: #define CALLER_FUNC(INPUT) ROOT_FUNC(#INPUT) (i.e. stringifying INPUT), a compiler error occurs because it is being asked to define an integer variable called v_"1" (an invalid name) and give it the value "1" (a non-integer value).
I know the preprocessor is fairly primitive, but is there any way of achieving what I'm after?
(Second edit for further clarification, I want CALLER_FUNC(INTA); to expand first to ROOT_FUNC(INTA);, then to int v_INTA = 1; – i.e. I want INTA to be expanded inside ROOT_FUNC, rather than outside it. I am looking for an answer in principle, not just any way to change CALLER_FUNC to produce the result int v_INTA = 1;, which would be trivial).
P.S.
In case you are wondering, I originally had a use case involving signal handling (e.g. taking macro names like SIGINT as inputs for nested macros), but got around these limitations by simplifying my structure and abandoning nested macros; hence this question is purely academic.
If you can expand the first macro to take two arguments, you could get it to work like this:
#define FUNC(intname, intv) int v##intname = intv
#define CALL_FUNC(intv) FUNC(_##intv, intv)
#define INT1 1
#define INT2 2
int main(void)
{
int INTD = 4;
CALL_FUNC(INT1);
CALL_FUNC(INT2);
CALL_FUNC(INTD);
}
The output (from GCC), looks something like this:
int main(void)
{
int INTD = 4;
int v_INT1 = 1;
int v_INT2 = 2;
int v_INTD = INTD; // not sure if you want the value of INTD here - I guess it doesn't matter?
}
Which I guess is what you are after - if I read your question right?
The token pasting prevents the preprocessor from expanding it out and simply generates a new token which is passed to the second macro (which then simply pastes that together to form the variable), the value (which is expanded) is passed down as the second argument..
EDIT1: Reading more through what you are after, I'm guessing the above trick is not what you reall want...ah well..
While I was looking at the library code, I found the below line
int number = config.nodes,i,fanout=numP/2;
I assume config is a pointer to something, but can there be commas in the statement? and make assignment like that?
This declares three variables. It's the same as:
int number = config.nodes
int i;
int fanout = numP/2;
Please note that commas are handled specially in declarations (and argument lists), C++ also has a "comma operator" which is not being used here.
It's valid, number is not being assigned the entire line you see though.
i and fanout are 2 other integers also being created at that time, fanout is also being initialized at this time.
That one line is equivalent to:
int number = config.nodes;
int i;
int fanout = numP/2;
Its basically many declaration:
int number = config.nodes;
int i;
int fanout=numP/2;
A more recognizable way to write this would be:
int number, i, fanout;
number = config.nodes;
fanout = numP/2;
I personally would never write something like your example because it takes too long for the reader to work out what's going on.
I have the following additions:
1) The whitespace is always ignored by the C++ compiler. So,
int number = config.nodes,i,fanout=numP/2;
is equivalent to
// declaring three variables number, i and fanout
int number=config.nodes, i, fanout = numP/2;
The comma here is to tell the compiler that i have more than one variable to declare. So, number will be initialized with config.nodes. If config is a pointer (as you mentioned above), then you cannot access member variables using . operator. You have to use -> instead of ..
2) The following line has different semantic:
// only one variable will be declared, which is number
int number = (config.nodes,i,fanout=numP/2);
Inside the parenthesis is an expression and the comma here is a comma operator. In this case, config, i, fanout and numP are previously defined. The value of comma operator is the value of last expression fanout=numP/2.
I'm not sure if the term's actually "Array Addition".
I'm trying to understand what does the following line do:
int var[2 + 1] = {2, 1};
How is that different from int var[3]?
I've been using Java for several years, so I'd appreciate if explained using Java-friendly words.
Edit: Thousands of thanks to everyone who helped me out, Occam's Razor applies here.
It's not different. C++ allows expressions (even non-constant expressions) in the subscripts of array declarations (with some limitations; anything other than the initial subscript on a multi-dimensional array must be constant).
int var[]; // illegal
int var[] = {2,1}; // automatically sized to 2
int var[3] = {2,1}; // equivalent to {2,1,0}: anything not specified is zero
int var[3]; // however, with no initializer, nothing is initialized to zero
Perhaps the code you are reading writes 2 + 1 instead of 3 as a reminder that a trailing 0 is intentional.
It is any different from int var[3]. The compiler will evaluate 2 + 1 and replace it with 3 during compilation.
How is that different from int var[3]?
In no way that I can see.
It isn't any different; it is int var[3].
Someone might write their array like this when writing char arrays in order to add space for the terminating 0.
char four[4 + 1] = "1234";
It doesn't seem to make any sense working with an int array.
var[2 + 1] is not different from var[3]. The author probably wanted to emphasize that var array will hold 2 data items and a terminating zero.
This creates an array of 3 integers. You're right, there is no difference whether you express it as2 + 1 or 3, as long as the value is compile-time constant.
The right side of the = is an initializer list and it tells the compiler how to fill the array. The first value is 2, the second 1 and the third is 0 since no more values are specified.
The zero fill only happens when you use an initializer list. Otherwise there is no guarantee of that the array has any particular values.
I've seen this done with char arrays, to emphasize that one char is reserved for a string terminator, but never for an int array.