TIL that in C++, you can declare variable in if statement



  • @LB_ said:

    I guess I misunderstood; I thought you were suggesting that nobody needed anything more than the basic 3-part for-loop inherited from C. Bad assumption on my part.

    Very bad assumption indeed. I was commenting purely on the history of variable definitions inside the parentheses of control statements.



  • @accalia said:

    not in python. assignment is forbidden inside the conditional of an if statement.

    Because in Python, assignments are a statement and not an expression. When you do x = y = 2, you're NOT actually doing x = (y = 2) like in C/C++.

    And apparently C++11 made variable declarations expressions too? Or pseudo-expressions or something.

    Man, C++ is really becoming something weirder with all these changes.



  • @accalia said:

    @Steve_The_Cynic said:
    Here's my contribution to the pendantry in this thread.

    if you're going to bring pedantry to the table, maybe use the same language?

    I noted that the assignment is disallowed in python, your counter example is in a C like language ('m going to assume standard C as it is the oldest, the syntax matches, and most c-like syntaxes maintain the same behavior)

    However, that is not how For loops work in Python.

    they work like this.


    Sorry, but in the context given, calling the = that appears in in-() variable declarations in C++ an assignment is wrong. I'm well aware that for loops don't look like that in Python.



  • @anonymous234 said:

    And apparently C++11 made variable declarations expressions too?

    The first post is commenting on a feature that has always existed in C++, it just contained C++11 syntax.



  • @anonymous234 said:

    @accalia said:
    not in python. assignment is forbidden inside the conditional of an if statement.

    Because in Python, assignments are a statement and not an expression. When you do x = y = 2, you're NOT actually doing x = (y = 2) like in C/C++.

    And apparently C++11 made variable declarations expressions too? Or pseudo-expressions or something.

    Man, C++ is really becoming something weirder with all these changes.


    Actually, no, it wasn't C++11. This was in C++98, and it didn't make variable definitions into expressions, nor pseudo-expressiobns. It merely allowed them in certain places inside the parentheses of flow-control statements.



  • TIL: not even C11 supports this feature: http://coliru.stacked-crooked.com/a/f0837f378f1200a0
    Which is weird because C is exactly where I'd expect this feature to be most useful.


  • FoxDev

    @Steve_The_Cynic said:

    Sorry, but in the context given, calling the = that appears in in-() variable declarations in C++ an assignment is wrong.

    in the initializer of a for loop.... eeh, i can see that argument. for an if() statement though.... i'm going to have to ask you to cite your sources on that one because if(var x = 5) {} or if ((q = getQ()) == true) {} both contain an assignment to me.



  • In C++ we have to be very specific about whether we are talking about an assignment or initialization because when you see an = it could be either one. They do very different things.


  • Banned

    @anonymous234 said:

    And apparently C++11 made variable declarations expressions too?

    No. for(int a = 0; int b = 0; int c = 0); still doesn't compile.


  • FoxDev

    @LB_ said:

    In C++ we have to be very specific about whether we are talking about an assignment or initialization because when you see an = it could be either one. They do very different things.

    okay then..... can you cite sources on which one is which in the two examples i gave above?



  • Well, I don't know how you do it, but when I was learning programming languages for the first time, especially C and C++, the difference between variable declaration, initialization, assignment and object creation was the most important thing (and confusing, yes) I had to learn.

    In terms of "knowing what the program does", the difference might generally not exist, but in terms of "understanding what the language is doing" it's fundamental, and sooner or later you have to deal with that.



  • If the = is after the first occurrence of the variable, you should consider it initialization and it will use the constructor and not the assignment operator. Otherwise it uses the overloaded assignment operator.

    SomeType x = 5; //initialization, calls constructor
    x = 7; //assignment, calls operator=()
    


  • @accalia said:

    @Steve_The_Cynic said:
    Sorry, but in the context given, calling the = that appears in in-() variable declarations in C++ an assignment is wrong.

    in the initializer of a for loop.... eeh, i can see that argument. for an if() statement though.... i'm going to have to ask you to cite your sources on that one because if(var x = 5) {} or if ((q = getQ()) == true) {} both contain an assignment to me.


    That's why it's a strong dose of pendantry. When the = occurs in a free-standing expression, it is indeed an assignment, but the = in a variable definition is, pedantically, an initialisation, not an assignment.

    Sources? Here's one: http://www.informit.com/articles/article.aspx?p=376876


  • FoxDev

    @LB_ said:

    If the = is after the first occurrence of the variable, you should consider it initialization and it will use the constructor and not the assignment operator. Otherwise it uses the overloaded assignment operator.

    ...... C++ is weird!

    /me wanders away while waving the white flag of warsurrender


  • Banned

    It might be pedantry, but it's very practical difference - specifically, it determines whether a constructor or an assignment operator will be called.


  • Grade A Premium Asshole

    Whoa. It gets stranger:

    $ cat blah.cpp
    #include <iostream>
    #include <stdlib.h>
    #include <time.h>
    
    bool doFun() {
      return rand()%2;
    }
    int main() {
      srand(time(NULL));
      if(bool thing=doFun()) {
        std::cout << "thing " << thing << "\n";
      }
      else if(true) {
        if(doFun()) {
          std::cout << "df 0, thing " << thing << "\n";
        }
        else {
          std::cout << "df 0, thing " << thing << "\n";
        }
      }
      return 0;
    }
    $ g++ -Wall -pedantic -std=c++98 blah.cpp && ./a.out
    df 0, thing 0
    

    It's also valid C++11.

    I did C++ for years and never knew that this existed, let alone its scoping rules.



  • @bugmenot said:

    It's also valid C++11.

    Barely - rand() is deprecated, and likely won't be in C++17 (or if it doesn't get removed then, it probably will be by C++20)


  • Grade A Premium Asshole

    It's been a while, but I think that these are all correct statements:

    Sometype x; //calls Sometype() and assigns the value to x
    Sometype y(7); //calls Sometype(7) and...
    x = y; //calls x.operator=(y) (or however you spell it)

  • Grade A Premium Asshole

    @LB_ said:

    Barely - rand() is deprecated

    Odd. G++ doesn't whine at me when I compile that code with --std=c++11 -Wall -pedantic

    Edit: You did notice that that's rand(3) from stdlib.h, right?



  • I believe that's because [[deprecated]] didn't get added until C++14.

    EDIT: all I know is rand() is going away eventually and you should use the <random> header instead.


  • Grade A Premium Asshole

    @LB_ said:

    ...all I know is rand() is going away eventually and you should use the <random> header instead.

    For real code? Fuck yes. For one-off posts to "lively" programming forums? Ehhhh.

    Edit: Hmm. Neither clang(3.6.2) nor G++(4.9.3) complain about the use of rand when I compile with --std=c++14. shrug



  • In Go, assignment and variable declaration can't be used as expressions, so the condition of an if statement can't have those in it.

    However, you can put a statement before the expression for the condition:

    if x := foo(); x > 3 {
        // something that uses x
    }
    

  • Banned

    @bugmenot said:

    Odd. G++ doesn't whine at me when I compile that code with --std=c++11 -Wall -pedantic

    g++ is generally very stingy about giving warnings. "-Wall -Wextra -pedantic" is the bare minimum you can get with, and if you want an actually reasonable level of warnings, you need at least fifteen more flags.


  • Banned

    @ben_lubar said:

    In Go, assignment and variable declaration can't be used as expressions, so the condition of an if statement can't have those in it.

    Funny thing is that C++ standards permits declaration in condition because condition is specifically defined as either declaration or expression.



  • What if your condition isn't just the truthiness of the new variable's value?



  • @ben_lubar said:

    However, you can put a statement before the expression for the condition:

    if x := foo(); x > 3 {
        // something that uses x
    }
    ```</blockquote>
    
    What would be the advantage of that? You can still hide a declaration in the if-statement, but you still have to name the variable twice? Well, is `x` scoped to the block?

  • BINNED

    @bugmenot said:

    ```
    else if(true)

    
    :wtf:


  • @accalia said:

    if(var x = 5) {} or if ((q = getQ()) == true) {} both contain an assignment to me.

    Your if (var x = 5) is wrong on syntax, you want auto instead of var. Fixing that, the two are fundamentally different. auto x = 5 creates a new symbol x and calls the constructor for the type (which auto infers from the other side), so it's essentially the same as int x = 5.

    q = getQ() on the other hand, requires that q already exist, and calls the assignment operator on it.

    So the first initializes a new variable, while the second assigns a value to an existing variable.

    @Steve_The_Cynic said:

    That's why it's a strong dose of pendantry. When the = occurs in a free-standing expression, it is indeed an assignment, but the = in a variable definition is, pedantically, an initialisation, not an assignment.
    It is not "pedantically". The expressions call different functions which can do different things. Which function it calls depends on whether it is an initialization or an assignment.

    @accalia said:

    C++ is weird!
    Only because everyone else is doing it wrong.

    @bugmenot said:

    calls Sometype() and assigns the value to x
    It doesn't "assign" the value to x. The "return value" of Sometype() IS x. Assignment requires that two things exist, the thing you are copying from, and the thing you are copying to. When you call a constructor, the thing doesn't exist until the constructor finishes, and afterwards the thing is.

    @ben_lubar said:

    What if your condition isn't just the truthiness of the new variable's value?
    Don't declare the variable in the parens.


  • Winner of the 2016 Presidential Election Banned

    @TwelveBaud said:

    The thing that all the C++ weenies are excited about is

    PHRASING.


  • area_pol

    As a c++ guru, my pedantry cannot stand this statement:

    @bugmenot said:

    Sometype x; //calls Sometype() and assigns the value to x

    It does not assign - it default constructs.

    @bugmenot said:

    x = y; //calls x.operator=(y) (or however you spell it)

    This copy assigns.



  • @blakeyrat said:

    I used the wrong fucking word, get the fuck over it. Nevermind, fuck this forum.

    I guess you're all perfect angelic beings who never make mistakes, so I don't belong. Keep piling on, I won't read a word of it.


    You're so pretty when you're angry.

    But we're not the ones that should "get the fuck over it". You are.



  • I'm going to take that as you completing my sentence rather than failed pedantry about it. Thus, I wholeheartedly agree and give you a like.


  • Winner of the 2016 Presidential Election Banned

    @TwelveBaud said:

    weenies are excited

    @Fox said:

    PHRASING.

    whoosh



  • I ...
    ...
    yup, you got me.

    RIP TwelveBaud's dirty mind 1988-2015


  • Winner of the 2016 Presidential Election Banned

    patpats Don't worry, I'll keep the spirit alive for you.



  • This doesn't work either in Java or ECMAScript.


  • Banned

    WHAT ARE YOU TALKING ABOUT YOU CAN DO new Date THERE JUST FINE!!!!!!!!!!!!!1111111ONEONETWO



  • @NedFodder said:

    Suddenly I like it much, much less.

    But

    I feel like there is some requirement that the new C++ standards mandate that for every useful feature added, at least two indifferent and/or terrible features must be added as well.

    Filed under: why don't we add a kitchen sink construction kit construction kit?


  • Banned

    @tar said:

    Filed under: why don't we add a kitchen sink construction kit construction kit?

    Because even thirty years after, C++ still has terrible RTTI support.



  • @anonymous234 said:

    Man, C++ is really becoming something weirder with all these changes.

    The one thing C++ needs these days is the one thing it's never going to get. Deprecation and abandonment of C compatibility: practically every nasty edgecase in the language is there because of the increasingly fantastical notion that someone might want to compile a .c file with the C++ compiler. (Protip: that's what a C compiler is for.)


  • Discourse touched me in a no-no place

    @tar said:

    I feel like there is some requirement that the new C++ standards mandate that for every useful feature added, at least two indifferent and/or terrible features must be added as well.

    Not just that, but the useful, indifferent and terrible features must interact strangely, and the standard library must be updated to use that interaction extensively. Which in large part is why some of us still prefer using C, despite C being really quite a low-level language by any reasonable definition: at least we can be sure we'll be able to link our code in a straight-forward way! :D 🐠



  • @LB_ said:

    In C++ we have to be very specific about whether we are talking about an assignment or initialization because when you see an = it could be either one. They do very different things.

    No. These are just words, you pedantic dickweed.


  • Grade A Premium Asshole

    @Onyx said:

    else if(true)

    :wtf:

    I was unclear on the scoping rules for variables declared in an if clause, so I created a nested scope with as few keypresses as I could at the time. 😛

    TRWTF is that the preview indicates that I can't put a code block inside a comment quotation.


  • Grade A Premium Asshole

    @Kian said:

    It doesn't "assign" the value to x.

    Well, if we're getting pedantic, the local variable declaration sets aside sizeof($Class) space on the stack, then $Class's ctor is called to twiddle the bits in that space until they're "right". ;)

    @NeighborhoodButcher said:

    It does not assign - it default constructs.

    $Class's default ctor twiddles the bits in the hole set aside by the variable's declaration (and maybe in heap holes, depending on how it was written) until the default ctor's code is done executing. Better? 😃

    @NeighborhoodButcher said:

    This copy assigns.

    Sure. And it does that by way of $Class::operator= (which might be written in terms of $Class's copy ctor.) 😄

    Edit: Why do the smilies look like they're laughing? 😦 (And why does the frowning face look horrified?)



  • @gleemonk said:

    What would be the advantage of that? You can still hide a declaration in the if-statement, but you still have to name the variable twice? Well, is x scoped to the block?

    Yes, that's the point. Also in scope in the else, if there is one. Typically used more for

    if val, err := foo(); err != nil {
      // handle error
    } else {
      // use val
    }
    // val and err are no longer in scope
    


  • @bugmenot said:

    Well, if we're getting pedantic, the local variable declaration sets aside sizeof($Class) space on the stack, then $Class's ctor is called to twiddle the bits in that space until they're "right". 😉

    Pfft. That's not pedantic.

    C++ doesn't have a "stack" and a "heap". Those are implementation details for managing automatic and dynamic object lifetimes. As far as the language is concerned, an object's lifetime starts after memory has been assigned for it and the constructor finishes running successfully (ie. doesn't throw an exception), and it ends when the destructor is called on it.

    This is a different operation from assignment, which operates on an object while it exists, not before.

    The view that the declaration makes space and the constructor then sets the bits is wrong, because in C++ the two actions are one. You are describing how C and init functions operate. C++ looked at that, said "That's retarded" and fixed it.

    You can still do it, if you wish, with placement new (which lets you create objects in memory you set aside for that purpose), but then you can't rely on automatic or dynamic lifetimes, you have to manage lifetime manually.

    You need to step a bit back from the hardware to grasp language level concepts. How the hardware models the language is not the language.



  • You can do that in Javascript:

    if (var a = something) {
      //do stuff 
    }
    

    ...except you'll never enter the code block, because a var expression always evaluates to undefined. The solution is to get rid of var, and then the expression evaluates to the expected value:

    if (a = something) {
      //do stuff
    }
    

    Now stuff gets done (and you just leaked a global, unless you remembered to define a somewhere up above).


  • Discourse touched me in a no-no place

    @blakeyrat said:

    Yes, I used the wrong word. Whoop-de-shit. My point still applies. So there's no need for the pedantic dickweedery.

    Well, there is, because you call people out all the time for doing essentially the same thing, Drax. The contours of your ability to understand metaphor are remarkably convoluted.


  • Discourse touched me in a no-no place

    @Fox said:

    @TwelveBaud said:
    The thing that all the C++ weenies are excited about is

    PHRASING.

    Why would the C++ weenies be excited about phrasing.

    <if i disliked getting whooshed like @accalia does I'd point out I'm deliberately missing the point here


  • Discourse touched me in a no-no place

    @Gaska said:

    WHAT ARE YOU TALKING ABOUT YOU CAN DO new Date THERE JUST FINE!!!!!!!!!!!!!1111111ONEONETWO

    *snerk* I've been wondering for YEARS why nobody makes that two joke.


Log in to reply