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.
Related
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);
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.
I'm having some trouble trying to understand proper usage of returned references in C++.
I have a class with a "big" object inside. I want to be able to use this object outside the class "read only" mode by returning a const reference to it.
The problem is I don't quite understand when objects get copied and when they don't.
Most of the questions about returning references where about returning objects allocating on the stack, which is not my particular problem, so I've prepared this little example:
class foo {
int a;
public:
foo() {
a = 3;
}
int& getInt() {
return a;
}
const int& useInt() {
return a;
}
void print() {
cout << "Inside class: a = " << a << endl;
}
};
int main() {
foo foo1;
int& goodRef = foo1.getInt();
int badRef = foo1.getInt();
goodRef = 4;
badRef = 5;
foo1.print();
foo1.getInt() = 6;
foo1.print();
int usingIt = 10*foo1.useInt();
}
What I understand is:
In int& goodRef = foo1.getInt(); nothing is copied, only the class owned a exists.
In int badRef = foo1.getInt(); badRef is a copy of a, so there are 2 separate objects, a and badRef.
So depending on what type of object catches the return value it is copied or it is not, so my question is:
When I use the reference like in int usingIt = 10*foo1.useInt(); is it copied and then used to multiply or only the value inside the class is used?
In this example it doesn't matter since it is only an int, but if it was a big object it would be a big deal.
Thanks!
Edit: Thanks to all the answers, but I get that having such methods inside a class is bad, I only put them for the sake of the example.
My actual class has a bunch of objects inside and an interface and bla bla, but one particular object is a glm::mat4. What i want is to be able to write something like glm::vec4 finalVec = foo1.getMatrix() * vec. But I dont want the whole matrix to be copied and then multiplied, rather I want to use the matrix that is already inside my class to perform the multiplication and at the same time not let the user modify it. I supposed something similar to useInt but with the mat4 would work but I wasn't sure and that's why I asked the question.
The glm specificatioon is very confuse for me, but I think the operator * is described as:
glm::mat4 operator* (glm::mat4 const & m, glm::vec4 const & v);
In your example int usingIt = 10*foo1.useInt();, the operator*(), depending on it's argument signature and internals, could cause a copy of your object to take place, at which point it would then be assigned (rather than copied again) into the value of usingIt. If your object was an aggregate or class object type, the copy using the object type's assignment operator would typically be elided using a compiler optimization step.
In general, anytime you are copying a l-value reference type (i.e., T& or const T&) to an aggregate or class object to a non-reference type (i.e., type T), a copy constructor, constructor, assignment operator, or conversion operator is invoked on the returned reference to the object.
If getInt returns int& why are you catching the return value in an int? What do you expect, that the compiler changes your source code to use a reference to int? It can't do anything else than copying the value of the object pointed by the reference.
On the other hand I think you have a bad example. Either you define a single method that returns a const reference:
int const & getInt() { return a; }
Or you provide two methods, one const and one non const:
int& getInt() { return a; }
int const & getInt() const { return a; }
Having both getInt and useInt does not stop anyone from using getInt and actually changing the value of the object in an way that is not intended.
When you use const reference you can only use const methods of this object. E.g. when you have STL vector you can get size, but you can't push_back elements to it.
vector<int> a;
vector<int> &c = a;
const vector<int> &b = a;
a.size();
b.size();
a.push_back(4);
c.push_back(4);
//our vector is now 4 4
//b.push_back(4); compilation error
In C++ you copy when you want to copy: for example
Function which copies:
int x(vector<int> b)
Function which doesn't copy:
int x(vector<int> &b)
You can read more here
I'm not exactly sure how to pose this question so I'll start with some example code:
//header file
class A
{
public:
A();
private:
int x;
std::string arr[x];
}
//cpp file
class A
{
public:
A()
{
/*code to get the value of x from a cmd call*/
}
}
Is this code valid? More specifically, can I have my string array in my header file be of size x, even though x is not specifically given a value until an A object has been created?
If this doesn't work, is my only other option to use a dynamically allocated array?
The code is not valid. You should use a vector instead.
class A
{
public:
A();
private:
int x;
std::vector<std::string> arr;
};
A::A () : x(command_gets_x()), arr(x) {}
Since arr is being initialized by the value of x, the constructor only works when x precedes arr in A (as it is in your definition). However, if the only purpose of x is to track the size of the array, it is not necessary, since a vector has the size() method.
class A
{
public:
A() : arr(command_gets_x()) {}
int x () const { return arr.size(); }
//...
private:
std::vector<std::string> arr;
};
It's not valid. Array sizes must be constant expressions. Yes, you'll have to use dynamic allocation, though not necessarily directly. You can just use std::vector.
No, that's not possible, for one C++ doesn't have variable length arrays, and further, the array size must be a compile time constant.
You can in the constructor allocate an array with new, or, better use a std::vector.
No, you can't initialize arrays with non-const expressions. This will work, and is close to your original intent:
class A
{
...
const int x = 3;
std::string arr[x];
};
And in the .cpp file:
int A::x;
I found that on my mac, in x-code I could do the following
int x = foo() // get some value for x at runtime
int array[ x ];
but that is seriously uncool!! I just read yesterday that some compilers allow dynamic allocation on the stack, but I would recommend that you stay well clear of that.
If the value of x is not known until runtime, then you cannot allocate an array of size x until runtime. Think about what the compiler does: can an array of size x be allocated if we don't know how big x is? The only remaining option is to allocate at run-time (aka dynamically allocate).
Is it possible to have a member pointer to an array in a struct? I would like to do something like below:
struct A
{
int array[10];
int sizeOfArray;
};
template<int size>
class B
{
public:
B(int (A::*arrayLocation)[size],
int A::*arraySize):
memberArray(arrayLocation),
memberArraySize(arraySize))
{
}
void setValue(A* pobj1)
{
for(int i = 0; i < pobj1->*memberArraySize; i++)
{
(pobj1->*memberArray)[i] = 1;
}
}
private:
int (A::*memberArray)[size];
int A::*arraySize;
};
int main()
{
A obj2;
B<10> obj1(&A::array, &A::sizeOfArray);
obj1.setValue(&obj2);
}
A pointer to an array in a struct is no different than a pointer to an array.
If what you want is a "pointer" that, given an object and an offset, returns the value of the corresponding element in some member array of that object, then you can write it as a "getter" function.
You can do this if you want to and if compiler supports it. But as #Lundin already said it is almost always a bad idea. Pointer to member is a feature that may be useful in a very rare cases. IMHO pointer to array member as well as pointer to array is never useful (as pointer to the first member is always used).