-1
// bind function: 
template<typename T> T bind(T& v) 
{   
    // Can I toy with the object v refers to? or that's undefined behaviour?
    // the object v refers to is not initialized yet, But the object has been allocated, so I can use that memory, I think?

    // The following 2 lines should be fine if I'm correct.
    // Which is my function is currently is doing (sorta)
    myvector.emplace_back(SQLType<T>(), (void*)&v);
    return 0;
}

SomeClass value = bind(value);

I would like to know if I can use the objectvalue before it has been initialized (which would happen when the bind function returns).

1 - Can I initialize the object myself and use it ? ie:

v = T();
v.something();  // if T is a class

2 - Or can I use the memory where it's stored? ie: as a temp raw buffer?

if (sizeof(v) > 4)
{
     ((char*)&v)[0] = 1;
     ((char*)&v)[1] = e + 5;       
}
Gam
  • 1,254
  • 1
  • 9
  • 18
  • 3
    This… can't compile. Could you post a [MCVE]? – Biffen Apr 28 '16 at 18:00
  • Downvoters please explain. – Gam Apr 28 '16 at 18:02
  • What is the significance of `// v = 0;`? – juanchopanza Apr 28 '16 at 18:03
  • @juanchopanza v is not initialized yet. I'm wondering if I can use it (assign a value, and hten use it, or use it's underlaying memory wherei t's stored) – Gam Apr 28 '16 at 18:04
  • 6
    Not a down voter but it is completely unlcear to me what you want to do. `v` is a reference so it is already initialized to refer to whatever you called `bind` with. – NathanOliver Apr 28 '16 at 18:04
  • @NathanOliver How is it initialized already? value1 will be initialized when the bind function returns (till then value1 has garbage data, and if it was a class, would be even worse). – Gam Apr 28 '16 at 18:06
  • 2
    You keep making edits, but your example remains as broken as ever. `bind` doesn't have a return type, `vector.emplace_back` is nonsense, and I can't figure out what *1* and *2* have to do with what you've asked above that. – Praetorian Apr 28 '16 at 18:12
  • `v` has to be initialized. It is a reference. What it refers to may not be initialized but `v` is and you saying it isn't is not correct. What you are talking about is initializing what `v` refers to. – NathanOliver Apr 28 '16 at 18:12
  • @NathanOliver I guess I should have been more explicit. The object it refers to is not initialized yet. – Gam Apr 28 '16 at 18:19
  • @Praetorian How does vector.emplace_back is no sense? vector is a container of a class that has a constructor that accepts 2 parameters, isn't that obvious? pseudo code that is easy to "fix" if you know the language. – Gam Apr 28 '16 at 18:22

3 Answers3

5

The below is stolen (slightly modified) from Mike Seymour's answer to a previous, similar question.


Inside bind, the value1 has been declared, so the name is available for use:

[C++11: 3.3.2/1]: The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer

You are allowed to use objects in limited ways before they are initialised. Basically, anything that doesn't depend on the value is OK:

[C++11: 3.8/6]: before the lifetime of an object has started but after the storage which the object will occupy has been allocated [...] any glvalue that refers to the original object may be used but only in limited ways. [...] using the properties of the glvalue that do not depend on its value is well-defined.

So, what you are doing is well-defined.

(Although, being ultrapedantic, I don't think it's specified when the storage for an automatic object is allocated, and 8.3.2/5 says that "a reference shall be initialized to refer to a valid object" without defining "valid", so there's scope to argue that it's not well-defined).

Community
  • 1
  • 1
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
0

What I see, your question is, how does memory allocation and memory initalization in c++ work?

I'm no expert myself, but this is my understanding of the concept:

  • If the variable is of primitive type, it will be allocated but not initialized.
  • If the variable is a object, a constructor is always executed (the default if no else is used) therefore the memory is allocated and MIGHT be initialized (depending on the constructor)

What this means: Yes, you should be able to use the memory, but don't trust the data

For your perspective, it seems you want to "receive" data from a function without having it "return it" and if the function itself doesn't care about the data, this way of handling variables is completly fine. (from my understanding)

Verified by "Lightness Races in Orbit " answer

user3252497
  • 121
  • 4
-2

Reference variables must always be initialised, and are always valid. If you want to refer to potentially invalid/uninitialized memory, use a pointer parameter (T*) instead.

You can use your parameter like you could with any variable of type T, the only thing that the & does it alter how it is initialized, which is done when the function is called, and will initialise it to refer to some lvalue expression. As v is already initialised, you cannot reinitialise it (well you could try new(&v) T(), but I wouldn't advise that unless you have called the destructor for v, (e.g. by v.T::~T()). (Note: v = T(); does not (re)initialise v, it will copy assign).

As for using it as a temp buffer, don't, use a pointer. (though I believe it is valid to use T& v as a buffer, and it would work as expected, it may confuse the compiler if your trying to store objects of the wrong time),

Isaac
  • 816
  • 5
  • 12