I have a vector in a header, like so:
extern std::vector<Foo> g_vector;
In the associated cpp file I have this:
std::vector<Foo> g_vector;
I also have a class Bar, and in it's constructor it will add some stuff to g_vector, like so:
Bar::Bar(/* stuff */)
{
// do things
std::cout << g_vector.size() << std::endl;
g_vector.push_back(somefoo);
std::cout << g_vector.size() << std::endl;
}
If I declare a Bar inside a function, like a sane person, it appears to work fine. However, if I want to declare a Bar outside of a function, weird things happen. For example, I have a Bar declared in MyFile1.cpp and in MyFile2.cpp, and because of my cout statements in Bar I can see the Foo get pushed into the vector, but when the next Bar runs its constructor the vector's size is 0 again. In other words, my output is
0
1
0
1
What gives? Just to be extra double sure, I also tried printing out &g_vector to make sure it was actually push_backing into the right vector, and the addresses all match. For what it's worth, it doesn't matter what order these things go in to the vector. I'm not concerned with the initialization order or anything.
Not sure what the issue really is, but I guess the following pattern will help solve it: define an accessor to the global variable and allocate it as a static function variable as shown below.
In the header file:
std::vector<Foo> &getGlobalVector();
In the cpp file:
std::vector<Foo> &getGlobalVector()
{
static std::vector<Foo> s_vector;
return s_vector;
}
This pattern is inspired from Andrei Alexandrescu's "generic singleton" implementation in Modern C++ design.
I've taken the habit of systematically using this pattern whenever I fell upon an existing global variable while maintaining existing applications (or in the rare occasions I actually chose to use one myself), and it may have helped in eliminating a couple of hard-to-reproduce bugs in said applications.
At any rate, this should really help avoiding any multiple-initialization or order-of-initialization related issue.
Order of initialization of global values is not defined.
Read here about the static initialization fiasco.
When you declare Bar in a function - the g_vector will be initialized before, because its promised to be initialized before the program runs. If Bar is a global variable - then you have a problem.
Related
For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value. I was under the impression that const variables cannot be edited. How would I go about this?
Edit:
Here are the directions for m_vin which is a member variable of an Object named Vehicle:
m_vin, a const int which represent a unique VIN–Vehicle Identification Number (no two vehicles can ever exist with the same m_vin).
In my program I am required to edit m_vin;
Word of caution: Modifying the value of such an object, no matter the technique used to do it, is cause for undefined behavior.
You could use:
int& ref = const_cast<int&>(m_vin);
ref = <new value>;
Don't blame me if your computer blows up.
It will be better to change the variable to be a non-const one.
int m_vin;
You should ask your professor/teaching assistant why is the const used there if the value of the variable is expected to be modified through out the code. That does not make sense.
You don't.
That's the whole point.
"For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value." - Don't do that. You'll invoke Undefined Behaviour.
Create a copy. Edit the copy. Save the copy back to "wherever".
Don't try to modify const variables. Even though the language gives you tools to write code that will do it and that will compile, you will have code that has no well defined behaviour. Don't do that.
Constants (also called literals) are fixed values once declared and initialized. unlike variables whose value can be altered, constants - as the name implies does not change, they remain constant. Constant must have to be initialized at the time of creating it, and new values cannot be assigned later to it.
Consider using a variable if the value will ever change during the program execution.
Do not do this. Ever. As stated by R Sahu, you can try const_cast to remove const'ness. However, this is not the only guard to fight with. Sometimes (especially if this is a global-scope defined item), memory page that contains the const items could be marked as read-only by OS (I met such a thing on Win XP). So, your attempt to modify const_cast'ed item could end up with Access Violation or similar.
Again: do NOT do this.
For my CS class I have a variable const int m_vin, throughout my code I am required to edit this value. I was under the impression that const variables cannot be edited. How would I go about this?
As others have pointed out, you can't, at least not directly. And it's not good programming to even try.
Here are the directions for m_vin which is a member variable of an Object named Vehicle: m_vin, a const int which represent a unique VIN–Vehicle Identification Number (no two vehicles can ever exist with the same m_vin).
Most likely your instructor is asking you to construct different objects with differing const int m_vin. If you do that you don't need to edit them after construction since each object is initialized with a different vin.
In my program I am required to edit m_vin;
However, assuming this is sort of a programming challenge, you can change a const member variable by instantiating a new object initialized with the different value. This is best done in a friend function so you can access private variables.
One way to accomplish this is using placement new together with a constructor that has all values needed to initialize the object. First save copies of all the values in the object locally. Use std::move for dynamic values. Next, call the destructor on the object. Then use placement new with the argument list needed to reconstruct the object with the new const value.
The following code replaces m_vin with a different value.
#include <memory>
#include <string>
struct Foo {
const int m_vin;
std::string stuff;
Foo(int m_vin_, std::string stuff_) : m_vin{ m_vin_ }, stuff{ stuff_ } {}
~Foo() {}
};
int main()
{
Foo foo1(1, "SomeString");
int ci = 42 // modify ci
std::string stuff = foo1.stuff;
foo1.~Foo(); // in case there is any dynamic objects in Foo
new(&foo1) Foo(ci, stuff);
std::string x = foo1.stuff;
}
But be warned. You should also use std::launder to guarantee the const member will be correctly read. This sort of hack, while legal (I think), harms the readability of the code. People reading the code will, reasonably, assume that const member variables will not change after they are constructed. So don't do it other than to pacify an instructor with a weird request.
I can initialize a member variable from a class for example with a constructor, of course but i can also do this by creating a variable of type class from which i could use it's members and initialize them by doing a function. So, i would like to know if the use of a constructor has something to do with reducing memory usage or real time enhancement that makes application more responsive.
Here i placed an example that i found on the internet. Trying to understand the real usage of a constructor in a c program as well in real life.
#include <iostream>
using namespace std;
class Line
{
public:
void setLength( double len );
double getLength( void );
Line();
private:
double length;
};
Line::Line(void)
{
cout << "Object is being created" << endl;
}
void Line::setLength( double len )
{
length = len;
}
double Line::getLength( void )
{
return length;
}
int main( )
{
Line line;
line.setLength(6.0);
cout << "Length of line : " << line.getLength() <<endl;
return 0;
}
In real life, in larger nontrivial projects, you forget to call your own initializers, leaving the object in uninitialized state. But you can't forget to call a constructor.
A constructor provides a syntax that can guarantee that your object is completely initialized when it is created.
Bugs abound when you create an object that requires additional function calls before it's not in an uninitialized state.
There are reasons to favor a constructor over a method, and often, these reasons depend on the context. Let's first consider the most obvious reason to favor constructors: immutable objects. An object that's considered to be immutable will never change its state after its initial construction (where it's declared and constructed). Often, such immutable objects keep their member variables private and allow you to create other instances of them based on various functions (e.g., a string's substring routine).
On the other hand, objects which go through various state changes throughout their life (e.g., a GameBoard) may require client calls to modify their state. However, even these objects will be initialized somehow (e.g., think Chess, Checkers, Sudoko, etc...) and should require a basic constructor to ensure that they started from a "sane" initial state.
Methods can initialize objects, but only sometimes is this legal. For instance a member variable that is a reference must be initialized in the constructor list, variables that require parameters, variables that are const, etc...
From a performance perspective, I don't know how I would resolve this aspect of the question... but writing clean and clear code always makes other programmers reading your code efficient and, dare-i-say-it, happy! :-)
One reason is that is reduces the scope for errors. Allowing an object to be constructed in an invalid/nonsensical state means it can be used in that state.
Line line;
// any read line.length is undefined behaviour
// What is the benefit of that?
line.setLength(6.0);
Constructors allow you to initialize instances in a valid and desired state, which means they can be used immediately without further manipulations.
Also, in regarding terminology, line.setLength(6.0) does not initialize the member, it modifies an already initialized one.
It's common wisdom that you can't return a reference to an array. I've read Why doesn't C++ support functions returning arrays? and one of the answers goes into long winded speculation that it's a design decision. Another answer suggests using a vector or struct instead (what??) and also says:
The array you return would degrade to a pointer though, so you would
not be able to work out its size just from its return.
But it's also common wisdom that you can preserve the size of an array by using a reference. The following works for example:
int arr[10];
int (&func())[10]
{
return arr;
}
int main()
{
int (&arr)[10] = func();
for (int i = 0; i < 10; ++i)
std::cout << i << " ";
}
Aside from the usual "you should use a vector or std::array" what's wrong with this approach? I'm unable to see why people care so much about returning an array when this is possible.
You seem dismissive of vector. However make sure you clearly understand that vector really is the C++ equivalent of an array in Java and many other popular languages. Don't be misled by the slightly different declaration syntax. The beast in C++ that uses [] is very different to a Java array.
Moving onto your question: Yes, you can return a C-style array by reference. Your code is correct. But there are very few use cases for it, which is probably why you haven't seen it before.
In modern C++, it is preferred to avoid using C-style arrays because they do not follow value semantics that other objects have. (For example, they cannot be returned by value from a function). They're an ugliness inherited from C that unfortunately it's too late to delete from the standard entirely.
std::array<int, 10> may look ugly to you at first, however it will behave nicely when you try to copy or move or return it.
The code you wrote is perfectly acceptable. There are a number of reasons why it isn't done more often:
The size of the array must be fixed at compile time. Many functions returning an array would like to return a variable number of elements.
The storage can't be local to the function, or if it is it must be static. You never want to return a reference to an object that no longer exists. It may appear to work, which is actually a bad thing - you won't notice your mistake right away. Your test case is quite artificial, you don't often return a reference to a global.
Another answer suggests using a vector or struct instead (what??)
A struct is copyable, so if you embed an array inside a struct you can return it like a normal value type. You can't do that with an array.
I'm unable to see why people care so much about returning an array when this is possible.
Because what you've done is just not very useful, it's just an accessor to a global array. You're not returning a new array, just the same one each time. This fails:
auto arr1 = func();
auto arr2 = func();
arr1[0] = 1;
arr2[0] = 2;
assert( arr1[0] == 1 ); // fails
The people who want to return an array from a function want to return a different array each time the function is called, not just a reference to the same one every time. The same way you can call a function returning int and it's a different value each time and separate calls don't return references to the same piece of state. You haven't solved their problem, you've just done something else.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can I use blocks to manage scope of variables in C++?
I came across some C++ code that resembled:
int main(void) {
int foo;
float qux;
/* do some stuff */
{
int bar;
bar = foo * foo;
qux = some_func(bar);
}
/* continue doing some more stuff */
}
Initially I thought that perhaps the original author was using braces to group some related variables, but being that the system under design doesn't have an abundance of memory I thought the author might have had the intention of having bar's scope resolve and any variables with in go away rather than have them around for the entire enclosing (foo's) scope.
Is there any reason to do this? It seems to me this shouldn't be necessary and that any modern compiler makes this unnecessary?
It seems to me this shouldn't be necessary and that any modern compiler makes this unnecessary?
Yes, modern compilers will optimize the memory usage in cases like this. The extra scope won't make the code faster or more memory efficient.
However, they can't optimize objects with destructors with side-effects as that would change the behavior of the program. Thus, this makes sense to do for such objects.
Is there any reason to do this?
It is useful to group related code together. You know that variables declared inside the braces won't be used anywhere else which is extremely helpful to know.
If you do that multiple times in a single method, that could result in that method taking up less stack space, depending on your compiler. If you're resource limited, you might be on a microcontroller, and their compilers aren't always as full-featured as x86 compilers.
Also, if you do that with full classes (instead of ints & floats), it lets you control where the destructor is called.
class MyClass;
int main(void) {
int foo;
float qux;
/* do some stuff */
{
MyClass bar;
qux = some_func(bar);
} // <-- ~MyClass() called here.
/* continue doing some more stuff */
}
In case of C/C++ one can try to limit conflicts between names (having function that is so long that requires one to scope variable this way is bad idea...) i.e. if there are multiple bar in the same function than scoping them this way will let one make sure they don't collide/override each other.
Normally scope inside function does not impact stack allocation size - stack is pre-allocated for all local variables irrespective of scope.
If the code is really like you've shown, it's probably pretty much pointless. Most compilers I've seen allocate the space for all local variables on entry to the function, and release it on exit from the function. There are a few other possibilities though.
If what you've shown as bar was an object of some class type (especially something with a destructor), the destructor would run on exit from the scope, even though the space wasn't released until later.
Another possibility is that there were really two inner scopes:
int main() {
// ...
{
// some variables
}
// ...
{
// other variables
}
}
In this case, the space for the local variables will be allocated on entry to main -- but, some variables and other variables will (typically) share the same space. I.e., the space that's allocated will be enough to accommodate the larger of the two, but will not (normally) be the sum of the two, as you'd use if you defined all the variables in main's scope.
intention of having bar's scope resolve and any variables with in go
away rather than have them around for the entire enclosing (foo's)
scope
This could be one (unimportant & legacy) reason.
The other reason is to convey it to the reader that int bar is just used within this scope to have a very small functionality (kind of function inside function). After that there is no use of bar.
Your code is equivalent of:
inline void Update (int &foo, float &qux)
{
int bar = foo * foo;
qux = some_func(bar);
}
int main ()
{
...
Update(foo, qux);
...
}
Most compiler will optimize call to Update() inside main() and inline it, which generates similar to what you posted.
It is likely meant to aid the programmer, not optimize the output, as a modern compiler is certainly smart enough to see a temporary variable is only used once.
On the other hand, for the programmer it adds a logical separation, it means "these variables are only needed for this code," and perhaps also "this code does not affect other code in this function."
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(): initialised(0)
{
cout << "Foo() gets called AFTER test() ?!" << endl;
};
Foo test()
{
cout << "initialised= " << initialised << " ?! - ";
cout << "but I expect it to be 0 from the 'initialised(0)' initialiser on Foo()" << endl;
cout << "this method test() is clearly working on an uninitialised object ?!" << endl;
return Foo();
}
~Foo()
{};
private:
int initialised;
};
int main()
{
//SURE this is bad coding but it compiles and runs
//I want my class to DETECT and THROW an error to prevent this type of coding
//in other words how to catch it at run time and throw "not initialised" or something
Foo foo=foo.test();
}
Yes, it is calling the function on a yet not constructed object, which is undefined behavior. You can't detect it reliable. I would argue you also should not try to detect it. It's nothing which would happen likely by accident, compared to for example calling a function on an already deleted object. Trying to catch every and all possible mistakes is just about impossible. The name declared is visible already in its initializer, for other useful purposes. Consider this:
Type *t = (Type*)malloc(sizeof(*t));
Which is a common idiom in C programming, and which still works in C++.
Personally, i like this story by Herb Sutter about null references (which are likewise invalid). The gist is, don't try to protect from cases that the language clearly forbids and in particular are in their general case impossible to diagnose reliably. You will get a false security over time, which becomes quite dangerous. Instead, train your understanding of the language and design interfaces in a way (avoid raw pointers, ...) that reduces the chance of doing mistakes.
In C++ and likewise in C, many cases are not explicitly forbidden, but rather are left undefined. Partially because some things are rather difficult to diagnose efficiently and partially because undefined behavior lets the implementation design alternative behavior for it instead of completely ignoring it - which is used often by existing compilers.
In the above case for example, any implementation is free to throw an exception. There are other situations that are likewise undefined behavior which are much harder to diagnose efficiently for the implementation: Having an object in a different translation unit accessed before it was constructed is such an example - which is known as the static initialization order fiasco.
The constructor is the method you want (not running before initialization but rather on initialization, but that should be OK). The reason it doesn't work in your case is that you have undefined behavior here.
Particularly, you use the not-yet-existent foo object to initialize itself (eg. the foo in foo.Test() doesn't exist yet). You can solve it by creating an object explicitly:
Foo foo=Foo().test()
You cannot check for it in the program, but maybe valgrind could find this type of bug (as any other uninitialized memory access).
You can't prevent people from coding poorly, really. It works just like it "should":
Allocate memory for Foo (which is the value of the "this" pointer)
Going to Foo::test by doing: Foo::test(this), in which,
It gets the value by this->initialised, which is random junk, then it
Calls Foo's default constructor (because of return Foo();), then
Call Foo's copy constructor, to copy the right-handed Foo().
Just like it should. You can't prevent people from not knowing the right way to use C++.
The best you could do is have a magic number:
class A
{
public:
A(void) :
_magicFlag(1337)
{
}
void some_method(void)
{
assert (_magicFlag == 1337); /* make sure the constructor has been called */
}
private:
unsigned _magicFlag;
}
This "works" because the chances _magicFlag gets allocated where the value is already 1337 is low.
But really, don't do this.
You're getting quite a few responses that basically say, "you shouldn't expect the compiler to help you with this". However, I'd agree with you that the compiler should help with this problem by with some sort of diagnostic. Unfortunately (as the other answers point out), the language spec doesn't help here - once you get to the initializer part of the declaration, the newly declared identifier is in scope.
A while back, DDJ had an article about a simple debugging class called "DogTag" that could be used as a debugging aid to help with:
using an object after deletion
overwriting an object's memory with garbage
using an object before initializing it
I haven't used it much - but it did come in handly on an embedded project that was running into some memory overwrite bugs.
It's basically an elaboration of the "MagicFlag" technique that GMan described.