1

I am working through a C++ book, to teach myself. The book I am working through Talks about narrowing through type conversions. It explains how a double can be narrowed to an int, and says "So what should you do if you think that a conversion might lead to a bad value? Use {} initializers to avoid accidents." It then gives a very limited example code and it has little context:

    double x{ 2.7 }; // OK
    int y(x); //error:double -> int might narrow

I tried running some code so I could see how it works, but my results were not what I expected:

    double test {1.2};
    cout << "First Line test = " << test << '\n';
    test = 3 / 2;
    cout << "Test = " << test << '\n';

From what I read, I was under the impression if I initialized the double test with the {} rather than the = version that I would be preventing the variable test from being allowed to later be narrowed to an int.

Is that not how it works?

I've read what's mentioned here and here about integer division, but it's still not clear for me.

If I was working in C I would use type casting:

double test = 0.0;
test = (double)3/2;
printf("test = %f", test);

My impression from reading was that if I did this in C++ it would accomplish the same:

    double test {1.2};
    test = 3 / 2;
  • Welcome to the wonderful world of _integer division_ :) (use the answer in the 2nd dupe for fixing) – πάντα ῥεῖ Feb 28 '21 at 19:44
  • My question was about the initialization using "{}" and not so much about the integer division. I was told this question was closed and pointed me to articles, which really didn't answer my question. Is there something I am doing wrong when I ask a question? – Chrisplusian Feb 28 '21 at 19:54
  • _"The result of this code was 3/2 truncated to 1."_ Your question is ***why?***, right? Did I misunderstood anything? Both of the linked articles answer that. You may [edit] your question and be more specific why these answer don't fit yours. That's the [usual course of action](https://meta.stackoverflow.com/questions/253521/what-can-i-do-if-i-believe-that-my-question-was-wrongly-marked-as-a-duplicate) here. – πάντα ῥεῖ Feb 28 '21 at 19:57
  • I apologize I may have made that confusing. My question was more about this: "From what I read, I was under the impression if I initialized the double "test" with the {} rather than the = version that I would be preventing the variable "test" from being allowed to later be narrowed to an int." I took C in college a long time ago, so C++ is COMPLETELY new to me. What I read in this book made me think if you initialized with "{}" then it would guarantee the result would remain of the type you initialized it as. When I tested that Idea it didn't work. So I was asking more about the "{}" part – Chrisplusian Feb 28 '21 at 20:03
  • Well, calculation of (constant) expression behavior , and initialization with the correctly applied type coversions are somewhat othogonal things, no? – πάντα ῥεῖ Feb 28 '21 at 20:05
  • I am sorry, I am sure that what I am asking may be completely clear to you, but the reason I asked the question is because I don't understand. What you pointed me to answers questions I wasn't asking. Is this the wrong site for new people to post questions? – Chrisplusian Feb 28 '21 at 20:10
  • Sorry I am not trying to make anything difficult, I am really just trying to teach myself programming. If I am asking questions on the wrong site (cause this isn't meant for people who don't know programming) I will try to find another place. Do you know of a site for new comers like me? – Chrisplusian Feb 28 '21 at 20:12
  • Well, you should have a basic understanding about what you're actually asking for. Maybe the book isn't that good. We keep a list of considerable ones here: https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – πάντα ῥεῖ Feb 28 '21 at 20:12
  • The book I am using is the second on your list. Its how I found the book. Not to sound condescending, but you are saying I should "have a good basic understanding or what you're actually asking for"? I do know what I am asking, but I don't know the answer, hence why I am asking. This really feels like you guys just don't want to be bothered with entry level questions. – Chrisplusian Feb 28 '21 at 20:20
  • Of course we're not denying entry level quesitons. I reopened your question, let's see if someone is able to give you a better answer than to be found in the duplicates I had linked. – πάντα ῥεῖ Feb 28 '21 at 20:30
  • Are you saying you believe that a double variable should be allowed to hold the value `1.2` but not the value `1.0`, depending on how it was originally initialized? Or are you saying you believe the result of the expression `3/2` should depend on how that result is later used? I'm trying to figure out where the misunderstanding lies, which part of this example are unclear to you. – Igor Tandetnik Feb 28 '21 at 21:38
  • 2
    The result of the expression `3/2` is a value `1` of type `int` (regardless what happens to that value next), under the rules of integer division. When that value is assigned to `double` variable, it's converted to `double` and becomes `1.0`. Therefore, after the assignment `test = 3/2;` the variable `test` holds the value `1.0` of type `double`. Hope this helps. – Igor Tandetnik Feb 28 '21 at 21:40
  • @IgorTandetnik Tandetnik, what I thought I was reading in this book, is that if I initialized the double with the "{}" notation, that it would not allow an arithmetic operation, or re-assignment to narrow the variable. So in C I would ensure that by casting: double test = 0.0; test = (double)3/2; printf("test = %f", test); What I thought this book was saying is if I initialized it as: double test {0.0}, that it would prevent the need for casting/or flag an error when I compile. It isn't prevening it, because it still truncates, so I am obviously not following properly – Chrisplusian Mar 01 '21 at 00:33
  • Why would a form of initialization of some variable affect the outcome of an expression that doesn't even involve that variable? Again, the value of the expression `3/2` is an integer 1, whether that value is later assigned to a double variable, or to an int variable, or printed, or simply discarded. `(double)3/2` works because the literal `3` is cast to `double` **before** the division; it's equivalent to `3.0/2`. Again, this has nothing to do with the variable on the left-hand side of the assignment. – Igor Tandetnik Mar 01 '21 at 02:31
  • I guess I see it differently. You say "Why would a form of initialization of some variable affect the outcome of an expression that doesn't even involve that variable?" I was viewing the left hand variable "test" as taking input from result of the expression. The verbiage used in the book to explain what the {} initializer does is: "So what should you do if you think that a conversion might lead to a bad value? Use {} initializers to avoid accidents". This is somewhat vague, so to me a bad value is one that loses accuracy when not intended like in the code I outlined above. – Chrisplusian Mar 01 '21 at 02:57
  • And I was trying to use {} initializers to avoid "accidents". So is there a better way to understand what the {} initializers accomplish? I read quite a bit about it, but all the explanations are over my head. I am starting to suspect there is quite a bit more to the story, and I need to just press on and forget this for now, with the hopes it will be revisited later. All the articles I can find on this talk about struct's, classes, and other things this book hasn't touched yet. – Chrisplusian Mar 01 '21 at 03:00
  • The result of the expression `3/1` is `1`. It does not depend on whether it is placed in curly braces, in round braces, in square braces, or without any braces. – n. m. could be an AI Mar 08 '21 at 09:20

1 Answers1

2

There are different initialization formats in C ++.

int x = 10; // Copy Initialization ( not much preferred )

int y = 10; // Value Initialization / Direct Initialization ( available in both old and new C++ )

int z {10}; // Uniform Initialization / Brace Initialization / List Initialization ( came with Modern C++)

Advantages of using uniform initialization

  1. Prevents narrowing conversion like you mentioned.But this is not the only advantage of using uniform initialization.
  2. Prevents Most Vexing Parse .To give a small example about most vexing parse. When we use parentheses "()" for initialization, there may be confusion between defining variables and defining functions. If this happens, the compiler gives priority to the function. I hope it will be useful for you, best regards.
east1000
  • 1,240
  • 1
  • 10
  • 30