Base-initializer?

A

Aneel

What is difference occurs for the following two classes:

class newclass {
private:
int x;
public:
newclass(int a){x=a;} // <<< constructor
};

AND

class newlcass {
private:
int x;
public:
newclass(int a): x(a){} // <<< constructor
};
 
A

Abhishek Padmanabh

Aneel said:
What is difference occurs for the following two classes:

class newclass {
private:
int x;
public:
newclass(int a){x=a;} // <<< constructor
};

AND

class newlcass {
private:
int x;
public:
newclass(int a): x(a){} // <<< constructor
};

The difference, in general, is that in the first example, the setting of
variable x with value of a, is an assignment while than in the second
example is an initialization utilizing the initialization list of the
constructor. However, in this case, the member is an 'int', a POD type. And
POD types are not default initialized even though you don't do that
explicitly in initialization list. Hence, x remains uninitialized in example
one until the assignment x=a is done. Had it been a non-POD type, for
example, a std::string member, it would have been first default initialized
to an empty string (via the default constructor of std::string) and then
assigned with the value of the passed string object. So, it becomes a
two-step process.

The way to initialize members in the second example is the preferred way.
 
P

Paul N

The difference, in general, is that in the first example, the setting of
variable x with value of a, is an assignment while than in the second
example is an initialization utilizing the initialization list of the
constructor. However, in this case, the member is an 'int', a POD type. And
POD types are not default initialized even though you don't do that
explicitly in initialization list. Hence, x remains uninitialized in example
one until the assignment x=a is done. Had it been a non-POD type, for
example, a std::string member, it would have been first default initialized
to an empty string (via the default constructor of std::string) and then
assigned with the value of the passed string object. So, it becomes a
two-step process.

The way to initialize members in the second example is the preferred way.

In addition, if x were instead a const int, you would need to use the
second form, as const ints cannot be assigned to - you need to
initialise them to the right value.
 
A

Ali Karaali

As a another point of view,

What is difference occurs for the following two classes:

class newclass {
  private:
    int x;
  public:
    newclass(int a)

x is already constructed here but wasn't initialized,

and you assigned a value to it,
but due to the variable a isn't initialized,
the assignment theorically is undefined at this point!
} // <<< constructor

};

AND

class newlcass {
  private:
    int x;
  public:
    newclass(int a)
:

x is constructed by a value which is perfectly normal and well
defined.
x(a)
{} // <<< constructor


};

Ali
 
A

Ali Karaali

Ali Karaali ha scritto:






Why should it be undefined? You are assigning a defined value to a
variable previously holding an undefined one, not reading the undefined
value (which would constitute UB).

Using an uninitialized variable is an undefined behaviour.
This is deeply theoric.
--
Christian Hackl
(e-mail address removed)

Milano 2008/2009 -- L'Italia chiamò, sì!

Ali
 
J

James Kanze

Using an uninitialized variable is an undefined behaviour.

Where did you get that?
This is deeply theoric.

Imaginary, rather.

Using the value of an uninitialized variable is undefined
behavior, but you can still use the variable in ways that don't
use its value: assigning to it, taking its address, etc.
 
A

Ali Çehreli

Where did you get that?


Imaginary, rather.

Using the value of an uninitialized variable is undefined
behavior, but you can still use the variable in ways that don't
use its value: assigning to it, taking its address, etc.

We came full circle... :)

I remember a thread 5-6 years ago, where I learned from you that
"using" an uninitialized variable would be undefined behavior even if
the use was to assign a value to it. I clearly remember that it was in
the context of pointers. Maybe you had meant it only for pointers and
that I may have extended it to other types.

I know Ali Karaali from a Turkish forum where we talked about this
same issue a couple of months ago.

Now you correct Ali in a way that contradicts what I think I had
learned from you years ago. :)

I know that it is ok in practice to assign to an uninitialized int,
but is it undefined behavior in the standard?

Ali
 
A

Ali Çehreli

We came full circle... :)

I remember a thread 5-6 years ago, where I learned from you that
"using" an uninitialized variable would be undefined behavior even if
the use was to assign a value to it.

I cannot find any thread that supports that claim, so I have to take
it back. Perhaps I heard it from another person, or perhaps I've
extended what I know from indeterminate pointer values that are trap
representations.

Going with Ali Karaali's "deeply theor[etical]" phrase, since the
standard is processor agnostic, it is possible that the value in x may
be a trap representation in a certain environment.

I found the following IBM article that supports that idea:

http://www.ibm.com/developerworks/power/library/pa-ctypes3/index.html

<quote>
Trap representations are most commonly seen on floating point and
pointer values, but in theory, almost any type could have trap
representations. An uninitialized object might hold a trap
representation. This gives the same behavior as the old rule: access
to uninitialized objects produces undefined behavior.

The only guarantees the standard gives about accessing uninitialized
data are that the unsigned char type has no trap representations, and
that padding has no trap representations.
</quote>

So, in theory

x = a;

expression above is undefined behavior.

Ali
 
J

James Kanze

We came full circle... :)
I remember a thread 5-6 years ago, where I learned from you
that "using" an uninitialized variable would be undefined
behavior even if the use was to assign a value to it. I
clearly remember that it was in the context of pointers. Maybe
you had meant it only for pointers and that I may have
extended it to other types.

You'll have to find and quote that thread, because I've never
intentionally said such a thing. (It's possible, of course,
that I misworded some statement. It's very easy for "using the
value of x" to become shorted to "using x", even if one knows
better.)

Are you sure you're not confusing the issue with e.g. comparing
pointers. To compare two objects, you have to access their
values, and that is undefined behavior if they aren't
initialized (and not just for pointers).

[...]
I know that it is ok in practice to assign to an uninitialized
int, but is it undefined behavior in the standard?

No. Formally speaking (although the standard doesn't word it in
quite that way), the undefined behavior occurs in the lvalue to
rvalue conversion. As long as you never do an lvalue to rvalue
conversion, there is no undefined behavior. (For the basic
types. There are a few additional constraints in the case of
class types.)
 
A

Ali Çehreli

You'll have to find and quote that thread, because I've never
intentionally said such a thing. (It's possible, of course,
that I misworded some statement. It's very easy for "using the
value of x" to become shorted to "using x", even if one knows
better.)

I apologize for saying that without proof. I hope you've seen my other
post that retracts my claim. It might have been another person who I
learned a lot from. ;)

I am sure that it was in the context of uninitialized pointer values,
which I now know must have been about trap representations.

Ali
 
T

tonydee

Going with Ali Karaali's "deeply theor[etical]" phrase, since the
standard is processor agnostic, it is possible that the value in x may
be a trap representation in a certain environment.

I found the following IBM article that supports that idea:

 http://www.ibm.com/developerworks/power/library/pa-ctypes3/index.html

<quote>
Trap representations are most commonly seen on floating point and
pointer values, but in theory, almost any type could have trap
representations. An uninitialized object might hold a trap
representation. This gives the same behavior as the old rule: access
to uninitialized objects produces undefined behavior.

The only guarantees the standard gives about accessing uninitialized
data are that the unsigned char type has no trap representations, and
that padding has no trap representations.
</quote>

So, in theory

  x = a;

expression above is undefined behavior.

I think you're misunderstanding the article. My understanding:

- a particular sentinel bit pattern (e.g. 0xFFFFFFFFFFFFFFFFFF for a
64-bit pointer) might be written into a variable when it's
uninitialised (or invalidated e.g. by free())
- before each attempted use of the variable's value, the current value
would be compared with that sentinel
- a "trap" (interrupt) would be raised if sentinel bit pattern is
found.

BUT, writing a new value into any variable does not involve an access
to the existing value, and would not involve any check for the
sentinel value.

Think about what the trap representations are trying to achieve, and
how they can be easily implemented (possibly with CPU support for
better performance), and hopefully the ambiguous usage of the word
"access" will be less confusing.

Regards,
Tony
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,147
Messages
2,570,835
Members
47,383
Latest member
EzraGiffor

Latest Threads

Top