casting

float boatLength;

iLength = (int)boatLength;

or

iLength = int(boatLength);

Does it matter?

iLength = (int)boatLength; is casting

iLength = int(boatLength); is calling a function. (not so good)

Why is it not so good?

I don't think it is a function call, it is functional-notation.

Type conversions

Quoting from that page:

Type casting

C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion, known in C++ as type-casting. There exist two main syntaxes for generic type-casting: functional and c-like:

double x = 10.3;
int y;
y = int (x);    // functional notation
y = (int) x;    // c-like cast notation

Also see the C++ Standard, 5.2.3:

A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) 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).

But int(something) can be overloaded. if "something" is a class. And whether or not it's a class is not always obvious. eg

int (someClassVariable.value) might be a simple int as a member of the class involved OR it could be a class in it's own right. In which case, the int (someClassVariable.value) could return something other than you'd expect. Especially if the folk that wrote the library decided they know better than you, what you really want when you call the int() notation.

I was making the presumption that the question was about "simple" types such as int, float, long etc.

[quote author=Nick Gammon link=msg=1985736 date=1417578391] I was making the presumption that the question was about "simple" types such as int, float, long etc. [/quote]In all fairness I think it was. But these things can be habit forming. If you think you're just doing a simple cast when you use int (whatever), then you'll tend to use it in all situations.

But int(something) can be overloaded.

Overloading conversion operators is for custom types that are incompatible with the LHS. To allow something to convert to int.

In which case, the int (someClassVariable.value) could return something other than you'd expect.

Nope, it returns an int. A conversion operators return type is the same as the conversion type, you cannot change that. If the class specifies its own conversion you can cast the class using (int) rather than int().

One method is only compatible with modifiers:

y =  int*(x);    //Incorrect
y = (int*) x;    //Correct

y =  const int(x);    //Incorrect
y = (const int) x;    //Correct

//You can use a typedef to work around this:
typedef const int cint;

y =  cint(x);    //Correct
y = (cint) x;    //Correct

And as the standards quote Nick pointed out, you need to use the method that looks like a function if the object you are casting to has multiple inputs:

str = String( analogRead( A0 ), HEX );

pYro_65: If the class specifies its own conversion (not a global) then you can cast the class using (int) rather than int().

Which is EXACTLY the point I was making!

But what is the problem, it converts to an 'int', not "something other than you'd expect"

pYro_65: But what is the problem, it converts to an 'int', not "something other than you'd expect"

It may still be an int but NOT necessarily the int you wanted.

It may still be an int but NOT necessarily the int you wanted.

That makes little sense.

Its exactly the int you wanted. A class isn't an int, and to be compatible with an int you need to let the compiler know how to do it. If you didn't have a conversion operator you shouldn't be expecting any int.

Conversion operators make different types compatible. And when there is only a single conversion to be done, you do not even need a cast (so what ever you're worried about is probably already happening :) ):

struct Foo{
  operator int() const { return i; }
  int i;  
};

struct Bar{
  float f;
};

void setup() {
  
  Foo f = { 5 };
  
  int i = f;
  float flt = f;
  Bar b = {f};
}

void loop() {}

Is there consensus?

Should one always use (int)x instead of int(x), or does it not matter?

Use the "What?" test. Of the two forms:

int x;
long val = 10L;

x = (int) val;      // Yep...got it.
x = int (val);      // What?

Ceteris paribus, if one of the two statements makes you say: "What?", use the other one. I prefer statements that instantly make sense, not ones that give me pause.

I’ve never heard of the “What?” test. It sounds circular. I want to understand the differences between these two forms, not avoid one because it might seem odd at first.

There’s nothing circular about it. As to understanding the difference, I think the earlier posts have answered that part, so perhaps this post should be marked solved.

It seemed to me that there was still some disagreement about it. Are they equal or not?

jboyton: It seemed to me that there was still some disagreement about it. Are they equal or not?

Under normal circumstances they are the same but, (int) something does exactly what it says on the tin. And it's potentially quicker. The value of something is retrieved and then converted into an int. Hence would be my preferred choice unless there's a reason to chose otherwise.

If you use int (something) you may be inviting some function to provide you with the value of something. This function may not necessarily return the value you were looking for.

jboyton:
Should one always use (int)x instead of int(x), or does it not matter?

Is there consensus?

We’ll see, eh?

I think (int)x is more commonly done, and therefore is more likely to be understood.

Just by comparison:

a && b
a and b

Are both valid C++ for logical ANDs, however quite a few people don’t realize about the second one, and assume that “and” is done with a typedef, for example. Recently I saw the claim that the “and” form was “another Arduino silliness”. No, it’s in the C++ standard.


On the basis that more people are likely to accept (int)x I would use that, but be prepared to see the other version in code, and don’t let your mind boggle too vigorously.

[quote author=Nick Gammon link=msg=1986783 date=1417636348]On the basis that more people are likely to accept (int)x I would use that, but be prepared to see the other version in code, and don't let your mind boggle too vigorously.[/quote]

I can see that. It's not a big deal. But at the risk of belaboring this point a little further, here's a line from code I have written:

rxBits = int16_t(rxBits * FAST_DIVIDE_MULTIPLIER) >> rxFastDivideShift;

Is it really better to do this instead?

rxBits = (int16_t)(rxBits * FAST_DIVIDE_MULTIPLIER) >> rxFastDivideShift;