I have this struct:
struct Snapshot
{
double x;
int y;
};
I want x and y to be 0. Will they be 0 by default or do I have to do:
Snapshot s = {0,0};
What are the other ways to zero out the structure?
They are not null if you don't initialize the struct.
Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members
The second will make all members zero, the first leaves them at unspecified values. Note that it is recursive:
struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members
The second will make p.s.{x,y} zero. You cannot use these aggregate initializer lists if you've got constructors in your struct. If that is the case, you will have to add proper initalization to those constructors
struct Snapshot {
int x;
double y;
Snapshot():x(0),y(0) { }
// other ctors / functions...
};
Will initialize both x and y to 0. Note that you can use x(), y() to initialize them disregarding of their type: That's then value initialization, and usually yields a proper initial value (0 for int, 0.0 for double, calling the default constructor for user defined types that have user declared constructors, ...). This is important especially if your struct is a template.
No, they are not 0 by default. The simplest way to ensure that all values or defaulted to 0 is to define a constructor
Snapshot() : x(0), y(0) {
}
This ensures that all uses of Snapshot will have initialized values.
In general, no. However, a struct declared as file-scope or static in a function /will/ be initialized to 0 (just like all other variables of those scopes):
int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0
void foo() {
struct { int a, b; } bar; // undefined
static struct { int c, d; } quux; // 0, 0
}
With POD you can also write
Snapshot s = {};
You shouldn't use memset in C++, memset has the drawback that if there is a non-POD in the struct it will destroy it.
or like this:
struct init
{
template <typename T>
operator T * ()
{
return new T();
}
};
Snapshot* s = init();
In C++, use no-argument constructors. In C you can't have constructors, so use either memset or - the interesting solution - designated initializers:
struct Snapshot s = { .x = 0.0, .y = 0.0 };
Since this is a POD (essentially a C struct) there is little harm in initialising it the C way:
Snapshot s;
memset(&s, 0, sizeof (s));
or similarly
Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));
I wouldn't go so far as to use calloc() in a C++ program though.
I believe the correct answer is that their values are undefined. Often, they are initialized to 0 when running debug versions of the code. This is usually not the case when running release versions.
Move pod members to a base class to shorten your initializer list:
struct foo_pod
{
int x;
int y;
int z;
};
struct foo : foo_pod
{
std::string name;
foo(std::string name)
: foo_pod()
, name(name)
{
}
};
int main()
{
foo f("bar");
printf("%d %d %d %s\n", f.x, f.y, f.z, f.name.c_str());
}
I know this question is super old, but this question popped up for me on google and I found this other way and figured I'd add it here:
Snapshot s {};
I'm not sure what C/C++ language version you need for this syntax.
Related
How to initialize two or more structures with the same data? This has to be done at compile time to be as default data for const structures that are non-member global variables.
EDIT:
And what about C?
Works for me:
// header
struct Foo {
int a;
int b;
};
extern Foo const x;
extern Foo const y;
// cpp file
Foo const x{2, 3};
Foo const y = x;
Edit: reinterpreted the question a little.
One way is:
#define DATA { bla,bla,bla,bla }
var a = DATA;
var b = DATA;
You can use the copy constructor to initialize the structs. (This requires the use of a helper function to ensure correct order of initialization.) If the structures are POD, this should be as efficient as regular compile-time initialization:
struct A {
int a;
double c;
};
A initial_data() {
return { 1, 2.0 };
}
A a = initial_data();
A b = initial_data();
I have a struct defined as:
typedef struct s non_t;
struct s {
char tName;
int rCount;
};
I then initialized it like this:
non_t *s = new non_t();
//s->tName = ???
//s->rCount = ???
So here, what do the values of s->tName and s->rCount get initialized to?? Are they null still? I want to copute something like:
s->rCount = s->rCount + 1
But in order for that to work properly I need s->rCount to be initialized to 0... I guess I'm just confused on how struct initialization really works?
As you add () in new non_t(), members would be value initialized, so member will have value 0 in your case.
With new non_t, the members would be default initialized, so uninitialized in your case.
Adding constructor would avoid those subtleties.
struct s {
s() : tName('\0'), rCount(0) {}
char tName;
int rCount;
};
or in c++11
struct s {
char tName = '\0';
int rCount = 0;
};
int and char cannot be null. The values will be undefined without a constructor that would initialize them.
struct s
{
s() : rCount(0) {}
char tName;
int rCount;
};
This would initialize rCount to zero.
If you need it to be initialized to 0, you should do it in a constructor. :)
Otherwise it'll be set to whatever random piece of memory it's allocated at.
struct s {
s() : tName(' '), rCount(0) {}
char tName;
int rCount;
};
In C++ struct works exactly like a class except all fields are public by default. You can make constructor that will initialize your struct with whatever default values you want.
I mean: I've a bunch of various structures/classes and all this a splendor shall be initialized with known in advance values. Those structures/classes will never be used other way except the preinitialized one, so there is no any need for constructor -- it's just a waste of extra memory, extra CPU cycles in program, and extra space in source code.
If you have access to a C++11 compiler, you can mark your constructors as constexpr to have them run at compile time. The benefit of this is that way down the road you can still construct your objects at runtime. e.g.
struct Point2D {
constexpr Point2D(int x, int y) : x_{x}, y_{y} {}
int x_, y_;
};
And now you can use Point2D's constructor to initialize it at compile time, instead of runtime:
Point2D p{3, 4}; // no runtime overhead.
Structures and classes can be initialized, in limited circumstances.
struct splendor {
int i, j;
char *name;
};
splendor iforus = { 1, 2, "Extra!" };
Additionally, if you never need the name of the type of the structure:
struct {
int k;
float q;
} anon_e_mouse = { 1, 2.3 };
You can just initialize the members at the point of declaration:
struct Foo
{
int i = 42;
double x = 3.1416;
std::string name = "John Doe";
};
This will set up the default values for all instances:
Foo f;
std::cout << f.i << std::endl; // prints 42
Note that this does not work with C++03, it requires C++11 support.
If a class (or struct) doesn't have a constructor, you can initialize it like so:
MyClass a = MyClass();
or
MyClass * b = new MyClass();
This is called value initialization and it usually amounts to zero-initialization.
C++11 gives you initializer_list.
#include <iostream>
struct s
{
int i;
};
int main() {
s s1={666};
s s2={42};
std::cout<<s1.i<<" "<<s2.i<<std::endl;
return 0;
}
You can also do in-class initialization for member.
#include <iostream>
struct s
{
int i=0;
};
int main() {
s s1; //s1.i = 0
//s s2={42}; //fails
std::cout<<s1.i<<" "<<std::endl;
return 0;
}
But you cant do bot at the same time.
It sounds like you are trying to implement the Singleton Pattern. When you do that, you still need a constructor (in fact, if you want to force it to be a singleton, you have to declare the default constructor as private).
class MySingleton
{
private:
// my data
MySingleton() { /* initialize my data */ }
public:
static MySingleton& GetInstance()
{
static MySingleton instance;
return instance;
}
// other functions
};
Related question: std::map default value for build-in type -- the subtle difference is I want more than to know whether the value is initialized to 0 or garbage, I want to specify a "constructor". I don't even care if it involves overhead with a class definition, I just want a clean "special" basic type. Even a syntactical hack would do. A non basic type is very easy to do this for, it is the entire job of the constructor.
I'd like to have a hashmap unordered_map<void *, int> but to have all its values default-initialized to -1 instead of 0 or garbage. This is because zero is a valid index, and I would prefer to default-initialize with a certainly invalid value.
I think I see a few sloppy ways this might be done with:
struct minus1 {
int i;
minus1() i(-1) {}
};
unordered_map<void*, minus1>
But I don't like this because I have to use .i to access the int, and it really just needs to be an int.
Okay so maybe I can have my map handle this:
struct PointerToIDHash {
std::unordered_map<void *, int> h;
PointerToIDHash() {
// ctor is powerless to affect the initialized values of future insertions into h
}
};
Well, crap now I have a .h too. Uhhhh. Can I inherit from a template? (sounds scary, but this might be a clean way if it can be pulled off)
How can I make a type that transparently acts like an int but is always initialized to -1?
I would prefer to know both how to do this with and without C++11.
#include <unordered_map>
#include <iostream>
using namespace std;
template<typename T, T default_value>
class SelfInitializer
{
public:
SelfInitializer(T x = default_value) : x(x) {}
operator T&() { return x; }
operator const T&() const { return x; }
private:
T x;
};
// demo
int main()
{
using minus1 = SelfInitializer<int, -1>;
unordered_map<int, minus1> m;
m[7] = 3; // assignment works
minus1 x = 3;
int y = x; // conversion to int works
int z = int(x); // explicit conversion works
cout << m[7] << endl;
}
add a conversion operator to int& so that your struct minus1 behaves like an int
struct minus1 {
int i;
minus1() : i(-1) {}
operator int&() { return i; }
};
Let's say I have the following struct:
struct myStruct
{
int x;
int y;
int z;
int w;
};
I want to initialize this struct to a default value when calling the following function. If it helps I'm looking for a simple zero initialization.
void myFunc(myStruct param={0,0,0,0})
{
...
}
This code however gives me compile error. I've tried VS2003 and VS2008.
NOTE: I have looked at other answers mentioning the use of constructor. However I want the user to see what values I'm using for initialization.
Adding default constructor in to your myStruct will solves your problem.
struct myStruct {
myStruct(): x(0),y(0), z(0), w(0) { } // default Constructor
int x, y, z, w;
};
Function declaration:
void myFunc(myStruct param = myStruct());
For modern C++ compilers which fully implement value-initilization it is enough to have the following value-initialized default value to zero-initiliaze data members of the myStruct:
myFunc(myStruct param=myStruct())
For other compilers you should to use something like this:
myStruct zeroInitilizer() {
static myStruct zeroInitilized;
return zeroInitilized;
}
myFunc(myStruct param=zeroInitilizer())
To avoid compiler specifics conside to use http://www.boost.org/doc/libs/1_53_0/libs/utility/value_init.htm