Lifetime and memory setup of this struct - c++

given a struct in the form ( declared before the main() or after )
struct
{
...
} bar;
I don't know how to manage this and how to treat this kind of object.
In general I would like a 360° answer about this but I also have few questions:
is this equivalent to declaring a static struct ?
it's legal and safe in C++11 ?
how to access bar by reference ?
For the last one I have prepared a small snippet here, that doesn't works but shows what I'm trying to achieve.

It's global object of unnamed struct. You cannot use this type as argument to function (since you doesn't know real type of the object). You can use decltype for this, but it doesn't needed since it's global object. It's legal and safe.
#include <iostream>
struct
{
double k1 = 0.123;
} bar;
int foo(decltype(bar)& a)
{
return a.k1-1;
};
int main()
{
std::cout << foo(bar) << std::endl;
return(0);
}
example
Really, since you have only one global object of this struct - you simply can use
#include <iostream>
struct
{
double k1 = 0.123;
} bar;
int foo()
{
return bar.k1-1;
};
int main()
{
std::cout << foo() << std::endl;
return(0);
}

This is simply a global variable. You can access it from any function or method in this compilation unit. The correct way of declaring it (in regard to your snippet) would be:
struct foo
{
double k = 1.23;
};
foo bar;
Now you can simply pass it by reference like this:
void f(foo & b)
{
b.k = 34.5;
}
In your snippet, bar is a variable of type being an unnamed struct:
struct <unnamed>
{
double k = 1.23;
} bar;
Since you did not give any name to your type, you're unable to pass it as a parameter to functions in the classic way. C++11 allows you to do so using the decltype directive:
struct
{
double k = 1.23;
} bar;
void f(decltype(bar) & b)
{
b.k = 3.45;
}
As for your questions:
It is not the same as a static struct. Static variables behave in a little different way. Static classes (= structs) too.
It is legal and safe to use global variables in C++11, but it is strongly advised not to use them, because they may easily break program's logic or architecture. Instead, one should use static classes or singletons.

No. static is a storage attribute. A struct is like any other data type: it can be static, volatile, auto, extern, and others defined by some implementations.
It is legal and safe.
Reference such a structure like this:
struct {
int field1, field2;
double yada, yada2, yada3;
} bar1, bar2;
bar1.yada3 = 3.14159265358979; // assign a field in the struct
bar2 = bar1; // copy contents of bar1 to bar2

1> bar is only single instance of its type. You can not have another instance of same type as bar. Its type is unnamed type struct, just like anonymous union. It is legal to have one such. It is more like global static(but not it is not static) just because you cannot refer it by extern keyword in other file.Any hack you have to refer it in other file ...?
3> It is legal to have it.
4> You can not declare reference to variable whose type you do not know. .Although u can access/modify same object anywhere in the file, so no need of reference. References are used to remove * and -> from code, mainly, otherwise what references do, is all possible with pointer.

is this equivalent to declaring a static struct ?
No, you'd use the static keyword for that, as for any other static variable. It's declaring a global variable, i.e. with static storage duration and external linkage, equivalent to:
struct Bar {...};
Bar bar;
it's legal and safe in C++11 ?
Yes.
how to access bar by reference ?
Since the type has no name, it has to be inferred, either by template argument deduction or, in C++11:
auto & ref = bar;
template <typename Bar> void bar_by_ref(Bar & bar) {
/* do something with bar */
}
Alternatively, in C++11, the type can be extracted by decltype:
decltype(bar) & ref = bar;

Related

Dynamic member of an Object in c++

A member of an object is defined as a.b. Is there a way to obtain the member dynamically through a vector? For example:
struct foo{
std::string bar;
};
vector <foo> baz;
baz[0].bar = "0";
Is there a way to access baz.bar while declaring bar? (Example)
void a(std::string b) {
//not sure if this is how it works
std::cout << baz[0].{b};
}
The only way one could use a string to access a member of an object would be like this:
void doStuff(std::string_view m) {
if (m == "bar") {
// Do stuff with bar
} else if (/* other members */) {
// Stuff with other members
}
}
It looks ugly. It is ugly. I wouldn't recommend that.
The reason C++ don't support lookup with strings is because at runtime, there is no information about types, names and any other information about the code itself. The addition of this data into compiled code would only result in memory bloat, and binary bloat, and would be useful in only a selection of code.
There are multiple features that allows similar semantics, but are type safe and faster than strings.
Solution 1: Pointer to members
C++ support pointer to members. They are a variable that can equal to a member of a class. For a given instance, you can access dynamically that member pointed to. Let me give you an example:
// This declares a pointer to member string data of the class foo
std::string foo::* someMember;
// Some member equals to the member bar
someMember = &foo::bar;
// We declare a foo
foo someFoo;
// Direct access to member
std::cout << someFoo.bar << std::endl;
// Access to the member via the pointer to member
std::cout << someFoo.*someMember << std::endl;
The neat thing with that is that you can choose the member at runtime:
// Points to a string member of class foo
std::string foo::* someMember;
if ( someCondition ) {
someMember = &foo::bar;
} else {
// baz is another string member of foo
someMember = &foo::baz;
}
foo someFoo;
// Will either access bar or baz depending on the condition
std::cout << foo.*someMember << std::endl;
The great thing about this is this is type safe. The pointer to member has a definite type of a definite class. This eliminates the problem of having a string equal to not something in your class or something of the wrong type.
If you don't like the syntax to declare a pointer to member, you can always use auto:
// The type of auto is `std::string foo::*`
auto someMember = &foo::bar;
Be aware that the type of someMember is inferred at compile time, and cannot change during program execution.
If I were to rewrite your function a in valid C++, it would look like this:
template<typename MemberType>
void a(MemberType foo::* m) {
std::cout << baz[0].*m;
}
The type MemberType will be inferred at compile-time, just like auto, so your function can work with any type of members. To know more about templates, please refer to your preferred C++ tutorial.
Solution 2: std::unordered_map
Sometimes you really need to lookup thing by strings. You'd like to dynamically declare new member in your class and dynamically access them. In that case, what you need is a map data structure: something that maps a value of some type to another value of some other type.
struct foo {
// We map some strings to some integers
std::unordered_map<std::string, int> values;
};
foo someFoo;
someFoo.values["bar"] = 12;
someFoo.values["baz"] = 15;
// Will print 12, then 15.
std::cout << someFoo.values["bar"] << std::endl;
std::cout << someFoo.values["baz"] << std::endl;
Again, type safety is here: you cannot accidentally assign a double into the map. The lookup type will always be strings and the accociated values will all be ints.

Does pointer-to-member make sense for a static member?

The pointer-to-member feature of C++ is interesting and powerful, but I'm wondering if it is or should be limited only to instantiated objects of a class, or if it is okay to point to a static member? The use cases aren't obvious to me for either static or non-static usage of the feature, though it does seem very interesting.
Pointers to statics are actually "normal" pointers, e.g.
class MyClass
{
public:
static int x;
static int f(int a)
{
return a+1;
}
};
// ...
int* pint = &MyClass::x; // pointer to static property
int (*pfunc)(int) = &MyClass::f; // pointer to static method
Pointers to non-static members are "special" because they need a class instance to dereference a value. They can be thought of as "offset of a member inside a class instance" (this is very rough, though, and cannot be applied to method pointers!).
Static members, on contrast, are actually much like namespaced global variables, possibly with restricted visibility. They have static memory addresses, which are independent of class instances — all instances share a single static member.
The following is legal C++11 code.
struct X
{
static void f() {}
static int i;
X() = delete;
};
typedef void(*funcPtr)();
int main()
{
funcPtr g = &X::f;
int * j = &X::i;
}
There is nothing wrong about taking adresses of static member data and functions. As you can see the class never gets instantiated at any time.

Initialise C-structs in C++

I am creating a bunch of C structs so i can encapsulate data to be passed over a dll c interface. The structs have many members, and I want them to have defaults, so that they can be created with only a few members specified.
As I understand it, the structs need to remain c-style, so can't contain constructors. Whats the best way to create them? I was thinking a factory?
struct Foo {
static Foo make_default ();
};
A factory is overkill. You use it when you want to create instances of a given interface, but the runtime type of the implementation isn't statically known at the site of creation.
The C-Structs can still have member functions. Problems will, however, arise if you start using virtual functions as this necessitates a virtual table somewhere in the struct's memory. Normal member functions (such as a constructor) don't actually add any size to the struct. You can then pass the struct to the DLL with no problems.
I would use a constructor class:
struct Foo { ... };
class MakeFoo
{
Foo x;
public:
MakeFoo(<Required-Members>)
{
<Initalize Required Members in x>
<Initalize Members with default values in x>
}
MakeFoo& optionalMember1(T v)
{
x.optionalMember1 = v;
}
// .. for the rest option members;
operator Foo() const
{
return x;
}
};
This allows to arbitrary set members of the struct in expression:
processFoo(MakeFoo(1,2,3).optionalMember3(5));
I have an easy idea, here is how:
Make the structure, just like you normally would, and create a simple function that initializes it:
struct Foo{...};
void Default(Foo &obj) {
// ... do the initialization here
}
If you have multiple structures, you are allowed in C++ to overload the function, so you can have many functions called 'default', each initializing its own type, for example:
struct Foo { //... };
struct Bar { //... };
void Default(Foo &obj) {...}
void Default(Bar &obj) {...}
The C++ compiler will know when to call the first or the second overload based on the parameter. The & makes obj a reference to whatever parameter you give it, so any changes made to obj will be reflected to the variable you put as parameter.
Edit:
I also have an idea for how to specify some parameters, you can do it by using default parameters. This is how it works:
For example you the following function; you can specify default values for parameters like this:
void Default (Foo &obj, int number_of_something = 0, int some_other_param = 10)
{ ... }

typedef struct : Default Initialization

typedef struct foo
{
bool my_bool;
int my_int;
} foo;
In the example above I understand that my_bool will be initialized randomly to either true or false but what about my_int? I assumed that my_int would be default initialized to 0 but that seems not to be the case.
Defining structs in this way appears to be incompatible with initialization lists so what is the best way to initialize my_bool and my_int to false and 0 respectively?
Types don't get "initialized". Only objects of some type get initialized. How and when they get initialized depends on how and where the corresponding object is defined. You provided no definition of any object in your question, so your question by itself doesn't really make much sense - it lacks necessary context.
For example, if you define a static object of type foo
static foo foo_object; // zeros
it will be automatically zero-initialized because all objects with static duration are always automatically zero-initialized.
If you define an automatic object of type foo without an initializer, it will remain uninitialized
void func()
{
foo foo_object; // garbage
}
If you define an automatic object of type foo with an aggregate initializer, it will be initialized in accordance with that initializer
void func()
{
foo foo_object1 = { 1, 2 }; // initialized
foo foo_object2 = {}; // initialized with zeros
}
If you allocate your object with new and provide no initializer, it will remain uninitialized
foo *p = new foo; // garbage in `*p`
But if you use the () initializer, it will be zero-initialzed
foo *p = new foo(); // zeros in `*p`
If you create a temporary object of type foo using the foo() expression, the result of that expression will be zero-initialized
bool b = foo().my_bool; // zero
int i = foo().my_int; // zero
So, once again, in your specific case the initialization details depend on now you create the object of your type, not on your type itself. Your type itself has no inherent initialization facilities and doesn't interfere with the initialization in any way.
Implement a default constructor:
typedef struct foo
{
foo()
: my_bool(false), my_int(0)
{
// Do nothing
}
bool my_bool;
int my_int;
} foo;
First off, the way that struct is declared is in the style of C. In C++ you should just do:
struct foo
{
bool my_bool;
int my_int;
};
In both C and C++, initialization is a separate step from allocation. If you always want to initialize the members of your struct, use default initialization syntax like this:
struct foo
{
bool my_bool{};
bool my_int{};
};
In older versions of C++ you need to manually write a default constructor that initializes all the members (the newer syntax above is just sugar for this):
struct foo
{
foo() : my_bool(), my_int() { }
bool my_bool;
int my_int;
};
As #sbi notes, if you want to manually initialize the struct, even without the default constructor, you can do foo myFoo = foo();
Have a default constructor:
struct foo {
foo() : my_bool(false), my_int(0) {}
bool my_bool;
int my_int;
};
You are not creating any object in that code. Initialization is done when you create objects, and is not particularly tucked by the way you declare the struct.
For instance the following initializes the boolean to false and the integer to 0
foo f = { };
Notice that you have just typdefed your struct. You have not created an object. Like others said you can omit the typedef in C++ and just declare the struct, and you are still able to refer to the type by just saying foo.
If you omit explicit initialization when you define an object, then for sure no initialization is done unless the object is defined at namespace scope or defined as static locally (in which case all members are zero-initialized) or the class has a user defined default constructor that does initialization accordingly.
As long as you are declaring the structs in a C-way, you could use zeromemory to null exactly sizeof(foo) bytes, therefore defaulting all values to 0.
In C++, you could define your structure with a constructor which would set your values to some default values if needed.
c and c++ don't initialize variables at all. They contain whatever happened to be in the memory location that they're now in previously. This also applies for member variables in classes and structs unless you specifically initialize them to a value.

Purpose of struct, typedef struct, in C++

In C++ it is possible to create a struct:
struct MyStruct
{
...
}
And also possible to do the following:
typedef struct
{
...
} MyStruct;
And yet as far as I can tell, no discernable difference between the two. Which is preferable? Why do both ways exist if there is no difference? Is one better than the other in style or readability?
Here are the differences between the two declarations/definitions:
1) You cannot use a typedef name to identify a constructor or a destructor
struct MyStruct { MyStruct(); ~MyStruct(); }; // ok
typedef struct { MyStructTD(); ~MyStructTD(); } MyStructTD; // not ok
// now consider
typedef struct MyStruct2 { MyStruct2(); } MyStructTD2; // ok
MyStructTD2::MyStruct2() { } // ok
MyStructTD2::MyStructTD2() { } // not ok
2) You cannot hide a typedef name like you can a name introduced via the class-head - or conversely if you already have a function or an object with a certain name, you can still declare a class with that name using the class-head but not via the typedef approach.
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // ok
void MyStruct() { } // (1) - ok Hides struct MyStruct
void MyStructTD() { } // (2) - not-ok - ill-formed
//> Or if you flip it around, consider in a new translation unit:
void MyStruct() { } // ok
void MyStructTD() { } // ok
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // Not ok
3) You cannot use a typedef name in an elaborated type specifier
struct MyStruct { }; // ok
typedef struct { } MyStructTD; // ok
int main()
{
void MyStruct();
void MyStructTD(); // ok - new declarative region
struct MyStruct ms; // ok - names the type
struct MyStructTD ms2; // not ok - cannot use typedef-name here
}
struct AnotherStruct
{
friend struct MyStruct; // ok
friend struct MyStructTD; // not ok
};
4) You cannot use it to define nested structs
struct S { struct M; };
typedef struct { } S::M; // not ok
struct S::M { }; // ok
As you can see, there is a discernible difference between the two. Some of the quirks of typedefs are a result of C compatibility (which is mainly why both ways exist i believe) - and in most cases, declaring the name in the class-head is more natural C++ - it has its advantages (especially when you need to define constructors and destructors), and is therefore preferable. If you are writing code that needs to be C and C++ compatible, then there is benefit to using both approaches. But if you are writing pure C++, I find specifying the class name in the class-head to be more readable.
The typedef version is a special case of
typedef foo bar;
which defines a new "type" bar as an alias for foo. In your case, foo happens to be a struct. In C, this was the only way to introduce new "types" (in quotes, because they are not really equivalent to int, float and co). In C++, this is not so useful, because C++ was designed to make definition of new types easier and more complete than C (at least at the beginnings of C++), and the typedef is not even necessary to refer to a previously declared struct (or class).
The latter is there for compatibility with C - use the first in new C++ code.
You would use a typedef so you do not need to specify the struct keyword when declaring variables of that struct.
Without typedef:
struct MyStruct foo;
With typedef:
MyStruct foo;
Basically you are making MyStruct appear as a new type so it also implements some level of type abstraction as programmers do not need to know explicitly what type it is. You can pass MyStruct into a function, manipulate the data in it and return it and the programmer need never worry about what actually happens.
Much of the C standard library uses typedefs for this reason.
The "struct MyStruct { };" construct implicitly defines the equivalent typedef, so typically that would be the preferred modern usage. There are still some uses for a typedef, mainly with pointer types to structures. E.g.
typedef struct MyStruct* MyStructPtr;
There are many answers that consider both approaches as equivalent, but they are not.
The typedef keyword is used to create a type alias, that is, it provides a new way of referring to another type. When you use typedef struct {} XXX; you are actually creating an unnamed type and then creating an alias XXX to that unnamed type. On the other hand, when you type struct XXX {}.
Please, read the answer by Michael Burr here (which is a better answer than the one accepted for that question.