I'm trying to write a function into a macro, but it is giving me a 'not assignable error'. My macro is this:
#define swapmacro(t, x, y) {t temp = x; x = y; y = temp;}
This is the code where I called it
int x = 4;
int y = 5;
swapmacro(int, 4, 5);
Then it gave me this error message:
stack.c:23:3: error: expression is not assignable
swapmacro(int, 4, 5);
^ ~
stack.c:7:43: note: expanded from macro 'swapmacro'
#define swapmacro(t, x, y) {t temp = x; x = y; y = temp;}
^
stack.c:23:3: error: expression is not assignable
swapmacro(int, 4, 5);
^ ~
stack.c:7:50: note: expanded from macro 'swapmacro'
#define swapmacro(t, x, y) {t temp = x; x = y; y = temp;}
^
swapmacro(int, 4, 5);
expands to this:
{int temp = 4; 4 = 5; 5 = temp;};
Neither 4 = 5 nor 5 = temp are valid expressions. Integer literals cannot be lvalues. Perhaps you meant to do this:
swapmacro(int, x, y);
Why not resort to something that uses a macros?
See swap
So the code could be
std::swap(x,y);
with type safety etc.
Related
I'm going through some code and came across a line like:
x = * y
What is the asterisk (*) in this case? I have some programming knowledge, but I'm new to C++. I think I grasp the concept of pointer variables, but the order and spaces make me think it's different than the *= operator or *y pointer.
In x = * y, y is most likely a pointer to something, in which case * is used to dereference the pointer, giving you a reference to the object to which y points and x = *y; copy assigns that value to x.
Example:
int val = 10;
int* y = &val; // y is now pointing at val
int x;
x = *y; // the space after `*` doesn't matter
After this, x has the value 10.
Another option is that y is an instance of a type for which operator* is overloaded. Example:
struct foo {
int operator*() const { return 123; }
};
int main() {
foo y;
int x;
x = *y;
}
Here, *y calls the operator*() member function on the foo instance y which returns 123, which is what gets assigned to x.
the order and spaces make me think it's different than the *= operator or *y pointer.
The spaces don't matter. * y and *y are the same thing, but it is indeed different from *=, which is the multiply and assign operator. Example:
int x = 2;
int y = 3;
x *= y; // logically the same as `x = x * y;`
After this, x would be 6.
Combining dereferencing and the mutiply and assign operator while using a non-idiomatic placement of spaces can certainly produce some confusing looking code:
int val = 10;
int* y = &val;
int x = 2;
x *=* y; // `x = x * (*y)` => `x = 2 * 10`
Would this kind of variable assignment work?
double a = 2.0,
x, y, z = 0.5;
Would the second line of code work properly and initialize x, y, z each to 0.5?
Your code leaves x and y uninitialized. However, a slight rearrangement can save you from repeating an initial value:
double a = 2.0, x = 0.50, y = x, z = x;
Variables that are declared earlier in a declaration are in scope of later declarations.
This is sometimes particularly useful when evaluating one initializer may have a non-trivial runtime cost. For example, in the following nested loop where m is a multimap:
for (auto it = m.begin(), kt = it, e = m.end(); it != e; it = kt)
{ // ^^^^^^^^^^^^^^^^^^^^^^^
// handle partition
for (; kt != e && kt->first == it->first; ++kt)
{
// ... handle equal-range
}
}
No, only z would be initialized .You have to write it like this:
double x = 0.50, y = x, z = x;
But you can write an assignment like this:
double x, y, z;
x = y = z = 0.50;
Simply No. Only z will be initialized.
If you try to print them afterwards
std::cout << a << " " << x << " " << y << " " << z;
you will get this kind of warning from the compiler:
warning: 'x' is used uninitialized in this function
For the sake of clarity I would use the second option that Rabbid76 suggested:
double x, y, z;
x = y = z = 0.50;
The second line of code:
double x;
x = 50.1;
actually has a return value. Usually, it is not caught, or used, but it is there. So x = 50.1 returns the value 50.1.
This implies that you could do:
double x,y,z;
x = y = z = 50.1;
And the value will make its way up the chain where x = y returns and the value isn't caught again. After that line is executed, x, y and z will all have the value 50.1.
If you want to assign to all three variables, write
x = y = z = 0.5;
which is equivalent to
x = (y = (z = 0.5));
The code that you present only assigns to z.
You can achieve what you want doing this:
x = y = z = 0.50;
You could do that in a single line like this:
double x = 0.5, y = 0.5, z = 0.5;
I need a working MAX macros (without(!) declaring main function) which assign 'r' the maximum of numbers 'a' and 'b'. This code breaks in compilation. How can it be fixed?
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
MAX(x, y, r);
Thanks for watching!
UPD: Some revision to clear the full task:
#import <iostream>
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 1;
int y = 1;
int r = 1;
int main()
{
MAX(x++, y, r);
std::cout << r;
return 0;
}
The result of this code is 1, and need to be 2. So I need another logic in my macros to consider all postfix increments
You can't use this macro outside of a function, because it's an arbitrary expression, that's why you're getting an error.
Just move the invocation of the macro into function scope and it will work:
#define MAX(x, y, r) ((x) > (y) ? (r = x) : (r = y))
int x = 10;
int y = 20;
int r;
int main()
{
MAX(x, y, r);
}
Using macros in this case is, however, unnecessary (unless this is just an exercise to learn macro usage); making max a function (or, better yet, using std::max) would be a better and less error-prone way.
It doesn't work because you can't put arbitrary expressions at file-scope. I have a couple of suggestions:
Don't use global variables unless you really, really have to. They'll just cause you pain.
Don't use macros unless you really, really have to. They'll just cause you pain.
Here's what I'd do:
int main()
{
int x = 10;
int y = 20;
int r = std::max(x, y);
//pass x, y and r as arguments to functions rather than using globals
}
This question already has answers here:
How does the Comma Operator work
(9 answers)
Closed 9 years ago.
int x = 0;
int y = 2;
int z = (++x, ++y);
I get that z is 3 because the value is taken from ++y, but why is ++y being chosen?
It's called comma operator. It evaluates ++x(now x is 1), then evaluates ++y(now y is 3) and assign value of y toz``
The ``comma operator groups left-to-right.
ยง 5.18
A pair of expressions separated by a comma is evaluated left-to-right and the value of the left expression is discarded.
Because (++x,++y) evaluates ++x first, then ++y and whatever was evaluated last is returned and assigned to z.
This uses comma operator. The equivalent is:
int x = 0;
int y = 2;
++x; // or x = x + 1;
++y; // or y = y + 1;
int z = y;
I'm trying to make a function that takes in either 1 or 3 parameters, and returns either 1 or 3 values (based on parameters passed).
If 1 parameter is passed then the function uses default values for the other 2 arguments.
If 3 parameters are passed then it uses those values.
bool foo( bool x, int &y = 0, int &z = 0) {
x = true; y = y + 1; z = z + 2;
return x;
}
Is this possible in C++ or am I confused with Java functions.
You can do it with two functions:
bool foo( bool x, int &y, int &z) {
x = true; // this isn't really what it does, is it?
y = y + 1; z = z + 2;
return x;
}
bool foo(bool x)
{
int a = 0, b = 0;
return foo(x,a,b);
}
Any function always returns only 1 value. Returning 2 or more values is not possible directly.
Indirectly, it happens when you pass parameters by reference. Since the two parameters &y and &z are passed by references, hence changes to them can be reflected back directly.
You can do this by passing by reference..
by doing so you are making a method that points to a memory location.
When that memory location is changed, then your value is changed.
Link
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr233.htm
You cannot do that this way. You can, however, overload that function with different number of parameters, and return, maybe, a std::vector or std::list with the results.
EDIT:
Being more sophisticated, you can use tuples for that:
typedef boost::tuple<bool,int,int> my_data_t;
my_data_t my_tuple(true, 1, 0);
then, you define your function like this:
bool foo( my_data_t & t)
{
t.get<0>() = true;
int& y = t.get<1>();
y = y+1;
int& z = t.get<2>();
z = z+2;
return t.get<0>();
}
and call it this way:
bool result = foo ( my_tuple );
then, out of the function, you'll see my_tuple.get<1>() (the corresponding to y) as 2 (1+1).
I am not sure what you are trying to do, but you can kind of return multiple values of different type using boost::tuple.
boost::tuple<bool, int, int> foo( bool x, int y = 0, int z = 0) {
x = true; y = y + 1; z = z + 2;
return boost::make_tuple(x, y, z);
}
int main() {
boost::tuple<bool, int, int> result = foo(x, 1, 2);
std::cout << boost::get<0>(result) << boost::get<1>(result) << boost::get<2>(result);
}
You could also use boost::optional, if you only want to return x, if only 1 parameter is passed.
Btw. tuple is available in C++11 too.