TIL that in C++, you can declare variable in if statement
-
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.
-
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 doingx = (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.
-
@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.
-
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.
-
@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 doingx = (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.
-
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 becauseif(var x = 5) {}
orif ((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.
-
And apparently C++11 made variable declarations expressions too?
No.for(int a = 0; int b = 0; int c = 0);
still doesn't compile.
-
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=()
-
@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 becauseif(var x = 5) {}
orif ((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
-
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
-
It might be pedantry, but it's very practical difference - specifically, it determines whether a constructor or an assignment operator will be called.
-
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.
-
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)
-
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)
-
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.
-
...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 }
-
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.
-
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?
-
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?
-
-
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.
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.C++ is weird!
Only because everyone else is doing it wrong.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.What if your condition isn't just the truthiness of the new variable's value?
Don't declare the variable in the parens.
-
-
As a c++ guru, my pedantry cannot stand this statement:
Sometype x; //calls Sometype() and assigns the value to x
It does not assign - it default constructs.
x = y; //calls x.operator=(y) (or however you spell it)
This copy assigns.
-
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.
-
-
I ...
...
yup, you got me.RIP TwelveBaud's dirty mind 1988-2015
-
patpats Don't worry, I'll keep the spirit alive for you.
-
This doesn't work either in Java or ECMAScript.
-
WHAT ARE YOU TALKING ABOUT YOU CAN DO
new Date
THERE JUST FINE!!!!!!!!!!!!!1111111ONEONETWO
-
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?
-
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.
-
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.)
-
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
-
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.
-
else if(true)
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.
-
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". ;)
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?
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?)
-
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
-
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 toundefined
. The solution is to get rid ofvar
, 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 definea
somewhere up above).
-
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.
-
@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
-
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.