Declaring variable in function call - c++

My struct:
struct Point {
int x;
int y;
Point(int nX, int nY) { x = nX; y = nY; }
Point() {};
};
Function:
void functionName(Point target);
And I want declare variable in function call: (pseudocode)
functionName(Point variable(5,0));
I'm writing in C or C++.

If you meant to construct a temporary Point and pass it to the function, you could (for C++):
functionName(Point(5,0));
Or for C++11:
functionName(Point{5,0});

[For C, ignoring the c'tor and d'tor]
struct Point {
int x;
int y;
};
Use a compound literal like this:
functionName((struct Point){5, 0});
Please not that the compound literal defined by this lives on the stack of the current context until the context is left.
To have it be deallocated immediately the function return, wrap the function call in its own context by doing:
{
functionName((struct Point){5, 0});
}

In case you want to use that variable, after the function finishes (I think you might as well do, since you want to give your argument a name), you would probably want to pass ref/pointer, for example :
void functionName(Point& target);
Point variable(5,0);
functionName(variable);
In case you dont really need the variable, you can simply pass an rvalue, by calling the constructor as argument :
functionName(Point(5,0));
notice that the 'target' will be destroyed when the function returns.

Related

Call member function of non-active union member

Does calling foo in the following code leads to UB?
using vec = std::array<int, 1>;
struct field0 {
vec data;
operator int() {
return data[0];
}
};
union a {
struct {
vec data;
} data;
field0 x;
};
void foo() {
a bar;
std::cin >> bar.data.data[0];
std::cout << bar.x;
}
According to standard, x and data have the same address, so it should be safe to cast this to vec*. Also, field0 and vec are layout-compatible, so it should be safe to inspect data via x.data or vice-versa.
However, we not just inspect x.data, we call non-static member function of x outside of it's lifetime (or do we? I can't find a reason why x lifetime should have started), so formally it's UB. Is it correct?
What I am trying to achieve is well-defined version of common approach to name array field like union a { int data[3]; int x, y, z};
UPD:
Sorry, during removing unnecessary details, layout compatibility between array field and "getter" was lost. Restored now.
I will need to use a values to function that takes int*, so going in other direction - declaring fields and overloading operator[] - is not an option.
Your code has undefined behavior. The initial common sequence rule wont help you here since you are not accessing a common member but instead you are accessing the entire object in order to call the member function1.
What I am trying to achieve is well-defined version of common approach to name array field like union a { int data[3]; int x, y, z};
The way to do this in C++ is to use a struct and operator overloading. Instead of having an array and trying to map it to individual members, you have individual members and then pretend that your class is an array. That looks like
struct vec
{
int x, y, z;
int& operator[](size_t index)
{
switch(index)
{
case 0: return x;
case 1: return y;
case 2: return z;
}
}
};
1: to call a member function is to pass that object to that function as if it was the first parameter of the function.

Is there a way to call a function expecting a pointer without creating variable?

I have this function call:
uint32_t func(uint32_t* a, uint32_t b)
I want to call it with an integer literal like this:
func(0, b);
where b is a uint32_t.
Is there any way I can do this without creating an intermediate variable?
I.e. I want to avoid doing this:
uint32_t a = 0;
func(a, b);
A helper class:
struct int_ptr {
int v;
operator int *() { return &v; }
};
int foo(int *a, int b);
void bar()
{
foo(int_ptr{0}, 0);
}
This results in a construction of a temporary int_ptr class, initializing its v member to 0. This gets passed as a parameter to a function that takes an int *, and int_ptr provides a suitable operator * method that passes the right pointer to the function.
This entire house of cards hinges on the fact that the int_ptr temporary exists until the end of the function call. You should pick a name for the helper class to underline that fact. If you always use it to pass a pointer to 0 to foo, then spell it out:
struct zero_value_to_foo {
int v=0;
operator int *() { return &v; }
};
int foo(int *a, int b);
void bar()
{
foo(zero_value_to_foo{}, 0);
}
So that using it in other contexts will look to be very much out of place, i.e.
int *p=zero_value_to_foo{};
This compiles, but leaves you with a dangling pointer; but hopefully the "zero_value_to_foo" label gives a honking clue that something is wrong here.
Another little thing you can do to help yourself from misusing this is to use a ref qualifier for the operator:
struct zero_value_to_foo {
int v=0;
operator int *() && { return &v; }
};
With this,
foo(zero_value_to_foo{}, 0);
still compiles, but not this:
zero_value_to_foo zero{};
foo(zero, 0);
The more that can be done to make it difficult to use this except in the context is meant for, the fewer opportunities there are for bugs to creep by.
I am assuming you want to pass a pointer to an integer 0, and not the 0 (NULL) pointer.
If you don't mind allocating dynamic memory you can do this:
func(new uint32_t(0), b);
However, then you'd have to make sure to deallocate the memory inside the function.
Alternatively, you can use an R-value references (c++11).
Then you can use the address of the reference as the pointer inside your function.
R-value reference syntax:
uint32_t func(uint32_t &&a, uint32_t b);

Structures and Function return values

I just started on STRUCTURES, played with them a little and got burnt!
This is the 1st exhibition:
#include <iostream>
using namespace std;
struct structure1{
int h;
int m;
int s;
} structVar;
int func(structure1 x);
int main(){
structure1 x;
structVar.h=4;
structVar.m=6;
structVar.s=7;
func(structVar);
cout<<x.h<<x.m<<x.s<<endl;
}
int func(structure1 x){
--x.h;
--x.m;
--x.s;
};
Its output is:
1072276636-21953788778
But I expect:
356
So I tried this way, exhibition 2:
#include <iostream>
using namespace std;
struct structure1{
int h;
int m;
int s;
} structVar;
struct returnstruct{
int val1;
int val2;
int val3;
}returnvalue;
int func(structure1 x);
int main(){
structVar.h=4;
structVar.m=6;
structVar.s=7;
func(structVar);
cout<<returnvalue.val1<<returnvalue.val2<<returnvalue.val3<<endl;
}
int func(structure1 x){
returnvalue.val1=--x.h;
returnvalue.val2=--x.m;
returnvalue.val3=--x.s;
};
And got my required output:
356
Problem is I cant explain why
This confusion is mostly due to variable scoping.
Key points:
function parameter names, such as x, are local to the function. If a name conflict exists with a globally scoped variable, the local function parameter will take precedence.
structs are passed by value, which means a copy is made and passed to the function as the parameter.
Case 1, you have the structure definition for a struct called structure1. In this global scope you also have an instance of it, called structVar. Then inside the scope of the main function, you have defined a local variable of type structure1 called x. The following lines
structVar.h=4;
structVar.m=6;
structVar.s=7;
are modifying the global scoped variable, structvar. Then you call
func(structVar);
This line modifies a copy of the global variable, structVar by passing it in as a function parameter to func. func uses the name, x for its reference to a structure1, but remember, since structs are passed by value, this name is referring to a copy of whichever struct you pass to it between the parens - func(structVar). This parameter name, x, has no relationship to the other x defined in main. It is specific or scoped to the body of the function, func.
You can explore this a bit, by changing the name of the function parameter to y, and first notice that it will not compile, complaining about x being undefined. This means that within the body of that function, it doesn't know about the x you've defined in main because that x is local aka scoped only to main. Contrast this with structVar, which is defined outside of any function's parameter list or body. structVar can be referred to within either of the functions because its scope is global.
cout<<x.h<<x.m<<x.s<<endl;
Using this understanding of scope, this line then can be seen to operating on the x defined in main which has not had its members (h,m,s) initialized or assigned any values, thus the 'weird' output.
Now, let's look at the second block of code you posted.
Here, you've added another global scope struct, called returnvalue. Now, you have two global scope variables, structVar and returnvalue. Because of that scope, structVar is visible inside of main, where you are modifying its member values (h,m,s).
Next, you are passing that global variable to func as its parameter, x. Remember, this is making a copy of structVar, which func calls x. So, x has the values of structVar's h, m, and s.
Inside of func, because of that global scope, it can see returnValue. Using the copy of structVar, again now called x, you are setting the values of returnvalue to the (pre)decremented (--) values of the parameter x. Since x is a copy of structVar and structVar had its members set to the numbers h=4, m=6, s=7, returnvalue then receives h=3, m=5, s=6. func then returns back to main.
Now, back in main, since returnvalue is global scope, main can see it and print out its values using cout, thus the output of 356
The value of structure1 x is passed by value. That means that the func function gets a copy of the argument that the caller never sees. So func can have no effect in this context unless it returns something.
You can either return the modified structure of pass x by reference, e.g., structure1& x. In the latter case x refers to the object that the function was called with.
#include <iostream>
using namespace std;
struct structure1{
int h;
int m;
int s;
} structVar;
int func(structure1 x);
int main(){
structure1 x;
structVar.h=4;
structVar.m=6;
structVar.s=7;
func(structVar);
I changed the line below
cout<<structVar.h<<structVar.m<<structVar.s<<endl;
}
I changed the function below too
int func(structure1 x){
--structVar.h;
--structVar.m;
--structVar.s;
};
Output is 356 as expected

Call constructor to initialize variables

I have the following class definition in C++ :
class foo {
private:
int a,b,c;
foo(); // constructor
void setup(int x, int y);
void some_function_that_changes_a_b_c();
}
foo::foo() {
a = b = c = 0;
}
void foo::setup(int x, int y) {
foo(); // <-- I use this to make sure a,b,c are initialized
a = x;
b = y; // <-- c is left unchanged!
}
void foo::some_function_that_changes_a_b_c() {
// here's some code that changes variables a,b,c
}
And then I have a code that uses this class:
foo *a = new foo;
a->setup(1,2);
a->some_function_that_changes_a_b_c();
a->setup(5,7); // <-- HERE IS THE PROBLEM
The problem is that on the second call to setup(), it doesnt run the foo() constructor to reset my values or a,b,c , so the c variable stays with the old value it was on the call to some_function_that_changes_a_b_c(), I tested this with the debugger and it seems like on the second call, foo() is addressing a different memory space for the variables.
Is there a way to fix this?
In C++, constructor is only called once when the object is constructed, and not anymore in your class method. In your code
void foo::setup(int x, int y) {
foo(); // ==> this line
}
A temporary foo object will be created, which is independent of the current this object, and therefore the a, b and c fields of this object will be unchanged.
In order to do what you have in mind, create a class method, say foo::reset(), and call it from inside foo::setup().
You should not call your constructor after the object has been created. Put the functionality into a protected reset() function that is called from both your constructor and the setup function.
Background: Your call to foo() in setup does not reinitialize the object, but create a second local object that is never used. In general, you should refrain from explicitly calling constructors unless you absolutely know what you're doing.
foo(); // <-- I use this to make sure a,b,c are initialized
Unfortunately, it doesn't do that. It creates and destroys a temporary object. You can't call a constructor directly; they are only used to initialise objects at the start of their lifetime.
You could reassign your object with a freshly initialised one:
*this = foo();
or you could move the body of the constructor into a reset function, and call that whenever you want to restore the initial state.
My preferred option would be use separate objects rather than trying to reuse a modified one, and to perform all the "setup" when initialising each object:
foo a(1,2);
a.some_function_that_changes_a_b_c();
foo b(5,7); // known to be in a freshly initialised state
What you are attempting to do is two-stage initialization. This is unnecessary and clumsy in C++. You need to realize two things
The constructor is called at the point of object creation
If you have an object to say f.setup(1, 2, 3); on, that means the constructor must have run already.
now:
foo f; // calls foo() with f
f.setup(1, 2, 3); // foo() has arleady been called
as Ying Xiong has pointed out, the foo() line creates a temporary object unrelated to the this you are working with.
Rather than two stage initialization (constructor, then initializer) you can have your constructor take variables and do the initialization
class foo {
private:
int a,b,c;
public:
foo(int x, int y, int z); // constructor
};
foo::foo(int x, int y, int z)
: a(x),
b(y),
c(z)
{ }
and then instead construct with the values you want
foo f(1, 2, 3);
if you need to "reset" the values each time setup is called, then you're best to use a reset function, or similar. Trying to call a constructor on yourself is possible but not very healthy.
void foo::reset() {
a = b = c = 0;
}

Deleting unreferenced dynamic memory

If i have the following part of the code in C++:
class X {
...
};
class Y {
public:
Y(X*) {...};
...
};
void main ()
{
X* px = new X;
new Y(px);
... // ***
}
How to delete object of class Y which was created in main? (*)
It is only allowed to add new lines of code instead of ..., not to change existing ones.
Disclaimer Never write code like this; avoid dynamic objects when you can, and if you really need them, always use RAII to manage them in a straightforward, exception-safe way.
Replace the first ... with:
#define void int
since void main () is invalid, and my compiler rejects it. This might not be necessary if your compiler is sufficiently dysfunctional.
Replace the second with:
WTF() = this;
to stash a pointer to the object that will need deleting in a static variable, defined later. Note that this only allows us to control one such object at a time; but, given the insane requirements, I can't think of a better way to make it available. If the constructor argument were available, then we could stash it in a non-static member of X instead; but the argument is unnamed, so we can't do anything with it.
Repace the third with:
static Y *& WTF() {static Y * y; return y;}
giving us a static variable to stash the pointer in. It can't be a global or static class member, since they must be defined outside the class definition.
Now we can replace the fourth with:
delete Y::WTF();
delete px;
Without the weird requirements, you could replace the whole mess with:
int main() {
X x;
Y y(&x);
}
The lesson from all this is: memory management in C++ is quite straightforward if you do it the right way, and insanely convoluted if you do it the wrong way.
I completely agree with Mike's answer, but I'd like to give an example of a working code, as opposed to Luchian's
class X {
public: void*data;
};
class Y {
public:
Y(X*px)
{ px->data = this; };
};
int main ()
{
X* px = new X;
new Y(px);
delete static_cast<Y*>(px->data);
return 0;
}