0

AFAIK the statement new (p_to_obj) myclass; is used to call constructor of a class for an already allocated memory region. Now, what does the statement new (p_to_struct_inst) mystruct; do for an already allocated instance of a struct that doesn't contain functions?

E.g.

struct mystruct
{
        int a;
        int b;
};

class myclass
{
        int member1;
        int member2;
        public:
        myclass() { //initialize members }
};

int main ()
{
        myclass * p_to_obj;
        p_to_obj = func_returns_addr_of_obj();
        //do some stuff, including members manipulation
        new (p_to_obj) myclass; //call constructor to initialize members (useful)

        mystruct * p_to_struct_inst;
        p_to_struct_inst = func_returns_addr_of_struct();
        new (p_to_struct_inst) mystruct;    //What is the use of this?    
}
Jarod42
  • 203,559
  • 14
  • 181
  • 302
ahmedaly50
  • 7,765
  • 3
  • 12
  • 7
  • 2
    It doesn't just call the constructor. It creates a new object. But concretely, in terms of generated assembly, it probably doesn't do much for `mystruct`. – François Andrieux Sep 16 '19 at 14:54
  • Having member functions or not has nothing to do with construction and destruction. Formally, overwriting an existing object without first destroying it produces undefined behavior. – Pete Becker Sep 16 '19 at 14:56
  • What do you mean by `doesn't contain functions`? Note, that you don't need to define constructor/destructor for class/struct to have one. – Dan M. Sep 16 '19 at 14:56
  • 3
    You should write a definition for `func_returns_addr_of_struct` so that it's clear what you're trying to ask. – Brian Bi Sep 16 '19 at 15:00
  • A struct always have a constructor unless you delete it... so it calls it. Other thing is that call would result in NOOP, but that's technicalities. – Swift - Friday Pie Sep 16 '19 at 15:06
  • You distinguish between `struct` and `class` but they are nearly same. The only difference is that `struct` is public by default and `class` is private by default. If this code is useful for `class` then it is also useful for `struct`. A struct also has a constructor and can contain methods. – Thomas Sablik Sep 16 '19 at 15:12
  • 1
    is it possible that you think classes and structs are two distinct concepts in c++? They are not. C++ has classes and `struct` and `class` are two different keywords that can be used to declare a class. The two imply different default access, but thats it. – 463035818_is_not_an_ai Sep 16 '19 at 15:14
  • 1
    "*for an already allocated instance of a struct*" It's not clear what you mean by this. Does `func_returns_addr_of_struct` actually *create* a struct of that type, or is it just allocating memory? Because those are two distinct actions in C++. – Nicol Bolas Sep 16 '19 at 15:40

1 Answers1

2

Type* ptr = new (void_ptr) Type( args... ) creates an instance of an object.

Without doing this, or something similar, there is no object to interact with there. Even if there are no methods, no constructors, and it is just a plain struct; without an object, using pointers-to-memory as if it pointed to an object is not generally legal in C++.

The abstract machine that C++ is specified in terms of has concepts that tend not to be compiled into assembly instructions. Among them is "is there an object there". The standard is carefully written such that "is there an object there" doesn't require any runtime state.

But the compiler is free to track where there are objects, and presume that when you interact with memory via a pointer you are interacting with an actual instance of an actual object.

This rules out a certain thing called "aliasing", where you have pointers to two kinds of objects, and you modify one, and the other one changes; aliasing (in general) isn't allowed in C++. This permits compilers to assume that when you edit what a double* points to, a int nearby doesn't have its value changed; there is no legal way for there to be both an int and a double at the same spot, and a double* can only be written to if it points at a double.

Similarly, a buffer of raw bytes? Guaranteed not to be a mystruct, at least until someone creates a mystruct there. What more, when a mystruct is created, the values of its members are guaranteed to be indeterminate, and when it is destroyed, any unobserved changes to the values of its members can be presumed never read by anyone.

That permits yet more optimizations, as useless writes are discarded and reads optimized away.

All of this breaks down horribly when you violate the aliasing rules of C++. These break downs only occur sometimes and in response to seemingly unrelated changes often. Many programmers thus ignore the aliasing rules, and entire code bases are compiled with flags disabling aliasing rules.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524