What's the Difference Between Type(Myvar) and (Type)Myvar

What's the difference between type(myVar) and (type)myVar?

There is no difference between type(x) and (type)x. These two are completely equivalent. Most people prefer type(x) for classes and (type)x for non-class types, but that's purely up to one's own choice. Both call constructors for classes with one argument x.

The preferred way for classes is type(x), because this allows passing more than one argument to the constructor, as in type(x, y). Trying to apply the other form, (type)x, y will not work: It casts x, and then applies the comma operator and evalutes y in isolation. Parentheses like (type)(x, y) do not help: This will evaluate x and y in isolation using the comma operator and then cast y to type.

For non-class types, such a cast is often too powerful. C++ has static_cast<type>(x) for roughly doing the reverse of an implicit conversion (such as casting base classes to derived classes and casting void* to another pointer), which often is what fits in. See When should static_cast, dynamic_cast and reinterpret_cast be used?.

stringstream is not a function, though. Doing function(x) will call it the function, but doing (function)x is illegal, beause there are two expressions next to each other, with no operator in between.


For those who don't believe this answer, and downvote it on gut feeling, please consult the Standard at 5.2.3/1

A simple-type-specifier (7.1.5) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).

What are the names of type(myVar) and (type)myVar? Are they both bad practice?

What is the name of these variants

  • type(expr) is known as a function-style cast.
  • (type)(expr) is known as a C-style cast.

and are they 'bad'?

Yes. First off, both are semantically completely equivalent. They are “bad” because they aren’t safe – they might be equivalent to a static_cast, but equally a reinterpret_cast, and without knowing both type and the type of expr it’s impossible to say1. They also disregard access specifiers in some cases (C-style casts allow casting inside a private inheritance hierarchy). Furthermore, they are not as verbose as the explicit C++ style casts, which is a bad thing since casts are usually meant to stand out in C++.


1 Consider int(x): Depending on x’ type, this is either a static_cast (e.g. auto x = 4.2f;) or a reinterpret_cast (e.g. auto x = nullptr; on an architecture where int is large enough to hold a pointer).

What is the difference between Class myVar = new Class() vs var myVar = new Class() in Dart?

It doesn't make any difference because Dart is inferring the variable type from the value you assign. You would typically mention a class when you don't initialize the variable :

var value; // This is a dynamic variable of null value
int value; // This is an int variable of null value

More on inference and the Dart type system

Is there a subtle difference between !myVar and myVar === undefined?

if(myVar === undefined) { // whatev }

This if statement will execute only if myVar is undefined.

Whereas the other statement:

if(!myVar) {
// whatev
}

Will execute if myVar is undefined or null or false or 0 or "" or any other falsy value.

So based on your requirement. If you want to execute for only undefined values, select first option else go for the second one.

Is there a difference between return myVar vs. return (myVar)?

UPDATE: This question was the subject of my blog on 12 April 2010. Thanks for the amusing question!

In practice, there is no difference.

In theory there could be a difference. There are three interesting points in the C# specification where this could present a difference.

First, conversion of anonymous functions to delegate types and expression trees. Consider the following:

Func<int> F1() { return ()=>1; }
Func<int> F2() { return (()=>1); }

F1 is clearly legal. Is F2? Technically, no. The spec says in section 6.5 that there is a conversion from a lambda expression to a compatible delegate type. Is that a lambda expression? No. It's a parenthesized expression that contains a lambda expression.

The Visual C# compiler makes a small spec violation here and discards the parenthesis for you.

Second:

int M() { return 1; }
Func<int> F3() { return M; }
Func<int> F4() { return (M); }

F3 is legal. Is F4? No. Section 7.5.3 states that a parenthesized expression may not contain a method group. Again, for your convenience we violate the specification and allow the conversion.

Third:

enum E { None }
E F5() { return 0; }
E F6() { return (0); }

F5 is legal. Is F6? No. The spec states that there is a conversion from the literal zero to any enumerated type. "(0)" is not the literal zero, it is a parenthesis followed by the literal zero, followed by a parenthesis. We violate the specification here and actually allow any compile time constant expression equal to zero, and not just literal zero.

So in every case, we allow you to get away with it, even though technically doing so is illegal.

const char myVar* vs. const char myVar[]

The pointer can be reassigned, the array cannot.

const char* ptr = "Hello World!";
const char arr[] = "Hello World!";

ptr = "Goodbye"; // okay
arr = "Goodbye"; // illegal

Also, as others have said:

sizeof(ptr) == size of a pointer, usually 4 or 8
sizeof(arr) == number of characters + 1 for null terminator


Related Topics



Leave a reply



Submit