a = b = new c?

Started by
36 comments, last by Paradigm Shifter 10 years, 10 months ago

There's also the type casting taking place:


T a = b = (T)new c();
mParameters[Name] = pParam = (ShaderParameter)new FloatParameter;

...or however it should be done.

I think it would be clearer to have the cast or temporary identified on a separate line.

Er, no. There is no casting.

Assuming a and b are of type pointer to c, then assigning the value of b to a requires no type cast, and the expression new c returns a value of type pointer to c, so again there is no type cast.

Again, assuming pParam is of type ShaderParameter* and mParameters is of type std::map<std::string, ShaderParameter*> and that FloatParameter is a class derived from ShaderParameter, there is no implicit type cast anywhere in the expression. Of course, those assumptions may not hold true, in which case the code woul be unlikely to compile anyway because it's missing explicit casts.

So, I think adding explicit casts where no cast is required would confuse the reader. I don't have a problem with the multiple expressions on the same line, but then I've had to maintain maybe a million lines of C code over the years and recognize the idiom. There are many things that are far more important to readability than that (eg. max 80 character lines).

Stephen M. Webb
Professional Free Software Developer

Advertisement

a = b = new c creates (allocates) one object of type c, then assigns the pointer to b, and then assigns the same pointer to a.

Careful, that isn't actually true.

a will point to b, while b will point to c. The fact that b currently points to c wont hold true if b is reassigned.

... I think I said that poorly.

http://objection.mrdictionary.net/go.php?n=6774974

Actually that captures it perfectly ( and is completely wrong! ;) ).

The address of b is assigned to a, not the value. This is exactly what I was warning of.

a = b = new c creates (allocates) one object of type c, then assigns the pointer to b, and then assigns the same pointer to a.

Careful, that isn't actually true.

a will point to b, while b will point to c. The fact that b currently points to c wont hold true if b is reassigned.

... I think I said that poorly.

http://objection.mrdictionary.net/go.php?n=6774974

Actually that captures it perfectly ( and is completely wrong! ;) ).

The address of b is assigned to a, not the value. This is exactly what I was warning of.

Why don't we just let a compiler answer it instead.

int main()
{
    int *a, *b;

    a = b = new int;

    std::cout << "value of a is " << a << std::endl;
    std::cout << "value of b is " << b << std::endl;
    std::cout << "address of b is " << &b << std::endl;
}

Is the value of a equal to the value of b or to the address of b?

a = b = new c creates (allocates) one object of type c, then assigns the pointer to b, and then assigns the same pointer to a.

Careful, that isn't actually true.

a will point to b, while b will point to c. The fact that b currently points to c wont hold true if b is reassigned.

... I think I said that poorly.

http://objection.mrdictionary.net/go.php?n=6774974

Actually that captures it perfectly ( and is completely wrong! ;) ).

The address of b is assigned to a, not the value. This is exactly what I was warning of.

Why don't we just let a compiler answer it instead.


int main()
{
    int *a, *b;

    a = b = new int;

    std::cout << "value of a is " << a << std::endl;
    std::cout << "value of b is " << b << std::endl;
    std::cout << "address of b is " << &b << std::endl;
}

Is the value of a equal to the value of b or to the address of b?

The value of a and b are the same ( for now ), the address of a and b are different.

The address pointed to by a and b will be the same (for now), the address OF a and b will be different.

So the conclusion is that the value of b is assigned to a?

So the conclusion is that the value of b is assigned to a?

OK, I am saying this poorly.

take

a = b = new c();

You change the value of b and a changes too, as a points to b, not c.

That is what I meant to say all along.

So, say using less abstract variables:

monster1 = monster2 = new Orc();

monster2 = new Gorgon();

At this point, people might think monster1 is still pointing at an Orc, it isn't, it's pointing at a Gorgon.

So the conclusion is that the value of b is assigned to a?

*initially*

What happens after "initially"?

So the conclusion is that the value of b is assigned to a?

*initially*

What happens after "initially"?

I edited.

a = b = new c creates (allocates) one object of type c, then assigns the pointer to b, and then assigns the same pointer to a.

Careful, that isn't actually true.

a will point to b, while b will point to c. The fact that b currently points to c wont hold true if b is reassigned.

... I think I said that poorly.

http://objection.mrdictionary.net/go.php?n=6774974

Actually that captures it perfectly ( and is completely wrong! ;) ).

The address of b is assigned to a, not the value. This is exactly what I was warning of.

No. First, a = b = new c is -- regardless of types or whether they're values or pointers --- equivalent to a = (b = new c). It means assign return value of "create c", to b, then assign b to a, not something different, ever. That's how the language is defined.

new c returns a pointer to the newly created object of type c (or throws), which necessarily means that b must be of type c* (pointer-to-c) or at least a compatible pointer (e.g. base class of c), or well, a compatible smart pointer. Otherwise this will not compile.

This, by consequence, means that a also has to be of type c*, because you cannot assign a pointer to "something else", say, an integer, or an object (not without a cast, a conversion operator, or a compile error, anyway), and a therefore also points to c (which is the value [of pointer-type] of b).

a does not point to b. It is assigned b's value (not its address!), which is a pointer to c. Otherwise, a would have to be of type pointer-to-typeof(b), not pointer-to-c.

Yes, you could of course be extra smart and define a as a class that has a constructor taking a pointer to type c, but that's a sophistry. It is technically possible to abuse the language in a way which makes this possible, but meh.

So the conclusion is that the value of b is assigned to a?

*initially*

What happens after "initially"?

I edited.

All right, let's ask the compiler again.

int main()
{
    int *a, *b;

    a = b = new int;

    std::cout << "value of a is " << a << std::endl;
    std::cout << "value of b is " << b << std::endl;
    std::cout << "address of b is " << &b << std::endl;

    b = new int;

    std::cout << "value of a is " << a << std::endl;
    std::cout << "value of b is " << b << std::endl;
    std::cout << "address of b is " << &b << std::endl;
}

This topic is closed to new replies.

Advertisement