3

In the code base, I often see people writing

void f(unsigned int){/* some stuff*/ }; // define f here
f(0) // call f later
unsigned int a = 0;
double d = 0;

Initialized number (0 here) not matching the declared type annoys me, if this is performance critical code, does this kind of initialization hurt performance?

EDIT For the downvoters:

I did search before I posted the question, c++ is famous for hidden rules, i didn't know integer promotion rules until someone commented under this question. For people saying "even stupid compiler won't do conversion at run time", here below is an example from this answer

 float f1(float x) { return x*3.14; }            
 float f2(float x) { return x*3.14F; }

These two versions have different performance, and to an unexperienced c++ programmer, I don't see much difference between my question and this example. And C++ is famous for hidden rules and pitfalls, which means intuition sometimes is not right, so why it is getting downvoted to ask a question like this?

Community
  • 1
  • 1
Allanqunzi
  • 3,230
  • 1
  • 26
  • 58
  • 1
    You mean `0` is not `unsigned int` ? – Hatted Rooster Apr 27 '17 at 15:40
  • 8
    Where you expecting to see? `unsigned int a = 0U`? No, there is no effect on performance. Integer promotion rules apply, making this well-defined, and since this is a *constant*, even the stupidest compiler would never emit code to do this conversion at run-time. – Cody Gray - on strike Apr 27 '17 at 15:42
  • `0` is a type of `int`, right? – Allanqunzi Apr 27 '17 at 15:43
  • ***does this kind of initialization hurt performance?*** No. – drescherjm Apr 27 '17 at 15:43
  • 1
    With questions like this you can often find the answer by [inspecting the assembly](https://godbolt.org/g/MoyLmI). Note that the code is identical. – NathanOliver Apr 27 '17 at 15:43
  • 1
    @Allanqunzi See http://en.cppreference.com/w/cpp/language/integer_literal for the rules on determining the type of an integrer literal. – François Andrieux Apr 27 '17 at 15:44
  • 1
    @NathanOliver I think you should never deduce language behavoir from assembly code. The way it was made in particular compiler would not guarantee that would be done everywhere. – Slava Apr 27 '17 at 15:45
  • and of course the way to find out if its a perf hit is to measure it on your platform (toolchain, OS,...) – pm100 Apr 27 '17 at 15:46
  • I expect this would be difficult to measure accurately. I mean if you try make sure the compiler does not optimize out what your trying to measure. – drescherjm Apr 27 '17 at 15:49
  • I just dont understand why it's getting downvoted, while the answer is upvoted, which at least means this is a valuable question. – Allanqunzi Apr 27 '17 at 15:53
  • 3
    No, the answer getting upvoted just means that the answer is *correct*. There's no indication that this question is useful or valuable. A common reason for downvotes on a question is lack of research effort, as suggested by the tooltip on the downvote arrow. That applies here. – Cody Gray - on strike Apr 27 '17 at 15:55
  • @CodyGray, please see my eidt. – Allanqunzi Apr 27 '17 at 16:18

2 Answers2

10

You are right that 0 is an int, not a double (0. would be) nor an unsigned int. This does not matter here though as int is implicitly convertible to those types and 0 can be represented perfectly by both of them. There's no performance implication either; the compiler does it all at compile time.

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • I would add that 0 is a special case in C++ – Slava Apr 27 '17 at 15:46
  • @Slava, you mean if for case of not `0`(like `1`, `1u`, `1.0`), it would be different? – Allanqunzi Apr 27 '17 at 15:50
  • 1
    @slava Are you talking about that little corner case of the C++ standard where it effectively defines `NULL` as 0? Something like: *"An integer constant expression with the value 0, or such an expression cast to type void\*, is called a null pointer constant."* This applies to pointers, but not other types. Otherwise, and in C, 0 is an integer literal and I can't think of anything special about it. – Cody Gray - on strike Apr 27 '17 at 15:53
  • @Allanqunzi there's no difference for `1`, `1u` or `1.` either. – Jesper Juhl Apr 27 '17 at 15:56
  • @Allanqunzi no I mean "To zero-initialize an object or reference of type T means..." – Slava Apr 27 '17 at 16:04
8

if this is performance critical code, does this kind of initialization hurt performance?

Very unlikely so. Even without any optimization enabled there is no reason for a compiler to generate code to get original value and convert to type of variable instead of initializing by converted representation of that type (if that conversion is necessary). Though this may affect your code if you use new style, that some people recommend to use in modern C++

auto a = 0U; // if you do not specify U then variable type would be signed int

to use this style or not is a subjective question.

For your addition:

float f1(float x) { return x*3.14; }            
float f2(float x) { return x*3.14F; }

this case is quite different. In the first case x is promoted to double calculations with double is used and then result is converted to float, while on the second case float is multiplied by float. Difference is significant - you either convert compile time constant of one type to constant of another or use calculations with that types.

Slava
  • 43,454
  • 1
  • 47
  • 90
  • Thanks! The way I see the reason why compiler is not smart enough to convert `3.14` to `float` makes me post this question, I just don't understand why people downvote my question. – Allanqunzi Apr 27 '17 at 16:32
  • The real reason why it is different with floating-point types is because the different floating-point types have different levels of *precision*. That means if you want to get consistent results, you need to ensure that you are preserving this precision throughout your intermediate results. That doesn't apply with integers, they all have the same degree of precision. Of course, it also matters that the floating-point example is a run-time operation, versus the compile-time integer example. I guess that's what you're trying to say in your last paragraph? – Cody Gray - on strike Apr 27 '17 at 16:37
  • @Allanqunzi it is not question of smartness of compiler, that language rule called Floating-point promotion. It has to do that. – Slava Apr 27 '17 at 17:13