Is this a valid assignment in C++? - c++

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.

Related

How to use int value in define function

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.

If statement inside parenthesis changes the value in a vector

I have a following problem.
I have two vectors correct_data_labels.label and data_labels.label , label is the vector<int > whereas data_labels and correct_data_labels are the instance of my class.
I have a method where I have if statement inside it. When I use IF statement, the argument that I used inside the parenthesis does an arithmetic and changes the value. As seen in the code below: When I run the code it replaces the value written inside an IF statement. So data_labels.label[row] is replaced by correct_data_labels.label[row]
unsigned int num=0;
double percentage=0.00;
for(register unsigned int row=0;row<data_labels.label.size();row++)
{
if((data_labels.label[row]=correct_data_labels.label[row]))
{
num=num+1;
}
}
percentage = (num/data_labels.label.size());
This code is written in c++, I suppose other programming paradigms can answer the above query too.
You used the assignment operator = instead of the equality operator ==. You probably got a warning about it which is why you have an extra set of parenthesis around the expression: suggest parentheses around assignment used as truth value (on my compiler at least)
Replace = with == to do the comparison instead of the assignment.

Is there a way of passing macro names as arguments to nested macros without them being expanded when the outermost macro is expanded?

(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..

Cannot understand for loop with two variables [duplicate]

This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
When I use two variables in a for loop with different conditions two conditions like I have used below i<3,j<2 the for loop is always executing till the second condition fails.
#include<iostream>
#include<conio.h>
using namespace std ;
int main()
{
int i,j ;
for(i=0,j=0;i<3,j<2;i++,j++)
{
cout<<"hello" ;
}
getch() ;
return 0 ;
}
In that code, hello is printed 2 times. Why?
If I use i<3,j<10, "Hello" is printed 10 times. I can't understand why the first condition is being neglected. Is it compiler dependent or something else?
Every thing works normal if I replace with conditions like || (OR) or &&(AND).An other thing is that I cannot initialize i and j in the for loop itself, it is showing me an error, but works fine when I declare variables in C style or one variable outside the for loop, why is it so?
Compiler I have used is Orwell Dev C++.
Thanks in advance.
for(i=0,j=0;i<3,j<2;i++,j++)
is equivalent to
for(i=0,j=0;j<2;i++,j++)
The comma expression takes on the value of the last expression.
Whichever condition is first, will be disregarded, and the second one will be used only.
The for loop consists of:
for(START_STATEMENT; CONDITION_EXPRESSION, LOOP_EXPRESSION) BODY_BLOCK
Where:
START_STATEMENT is any single statement, which may include variable declaration. If you want to declare 2 variables, you can write int i=0, j=0, but not int i=0; int j=0 because the latter are actually 2 statements. Also node, that variable declaration is a part of statement, but cannot be a part of (sub) expression. That is why int i=0, int j=0 would also be incorrect.
CONDITION_EXPRESSION is any single expression that evaluates to a boolean value. In your case you are using a coma operator which has the following semantics: A, B will do:
evaluate A (it will evaluate, not just ignore)
ditch the result of A
evaluate B
return B as the result
In your case: i<3,j<2 you are comparing i<3, you are just ignoring the result of this comparison.
Comma expressions are useful when the instructions have some side effects, beyond just returning a value. Common cases are: variable increment/decrement or assignment operator.
LOOP_EXPRESSION is any single expression that does not have to evaluate to anything. Here you are using the comma expression again, ignoring the result of the left-hand-side. In this case however, you are not using the result anyway, and just using the ++ side effect - which is to increment the values of your variables.
BODY_BLOCK is either a single statement or a block, encapsulated with curly braces.
The above for can be compared to:
{
START_STATEMENT;
while(EXPRESSION) {
BODY_BLOCK;
LOOP_EXPRESSION;
}
}
The c complier always used second condition.
therefore j<2 is used.
use this for loop
for(i=0,j=0;j<10;i++,j++)

C++ compile-time expression as an array size

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.