By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,188 Members | 844 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,188 IT Pros & Developers. It's quick & easy.

Variable declaration and while loops

P: n/a
Hello,

This seems like an extremely basic question, and I'm a bit embarassed
that I can't answer it myself.

I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)
{
/* something */
}

which my compiler has been supporting for a good few years. Under GCC
this doesn't compile. At first it didn't even occur to me that maybe
the code was invalid. I just thought GCC was being stupid. But then
it occurred to me that this probably really isn't valid C++, and that
my compiler has just been breaking the rule. Can anyone shed some
light? Can you declare a variable in a while loop similar to how you
can with a for loop?

Jun 18 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Zachary Turner wrote:
Hello,

This seems like an extremely basic question, and I'm a bit embarassed
that I can't answer it myself.

I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)
Drop the "!= 0" part and you'll have a standard construct.
{
/* something */
}

which my compiler has been supporting for a good few years. Under GCC
this doesn't compile. At first it didn't even occur to me that maybe
the code was invalid. I just thought GCC was being stupid. But then
it occurred to me that this probably really isn't valid C++, and that
my compiler has just been breaking the rule. Can anyone shed some
light? Can you declare a variable in a while loop similar to how you
can with a for loop?
No, you cannot. Those are two different statements and they have
different syntax. You can, however, declare/define/initialise an object
in a 'while' or 'if' parentheses, but you cannot do it in an expression.

if (int i = getint())

is valid

if ((int i = getint()) != 0)

is not, although the semantics are the same. (you can replace 'if'
with 'while' above).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 18 '07 #2

P: n/a
Hi

Zachary Turner schreef:
I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)
{
/* something */
}

which my compiler has been supporting for a good few years. Under GCC
this doesn't compile. At first it didn't even occur to me that maybe
the code was invalid. I just thought GCC was being stupid. But then
it occurred to me that this probably really isn't valid C++, and that
my compiler has just been breaking the rule. Can anyone shed some
light? Can you declare a variable in a while loop similar to how you
can with a for loop?
Yes, but you may not parenthesize it (a declaration is not an
expression). So, correctly, your code would read:

while(int i = getint())
{
/* something */
}

The condition in an if-, while-, switch- and even in a for-statement may
be a declaration with initialization. In this case, the condition
evaluates to the value of the declared variable, converted to bool.

Markus
Jun 18 '07 #3

P: n/a
"Victor Bazarov" <v.********@comAcast.netwrote in news:f562h2$sdg$1
@news.datemas.de:
Zachary Turner wrote:
>Hello,

This seems like an extremely basic question, and I'm a bit embarassed
that I can't answer it myself.

I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)

Drop the "!= 0" part and you'll have a standard construct.
Personal style: ick. I prefer to explicitly test against 0 when dealing
with ints (I also prefer to explicitly mention NULL when dealing with
pointers too.) If the expression type is bool (or 99.9% of the time
intended to be treated as a bool, such as the void* return of streams.
It's not really intended to be used as a pointer, but it prevents other
unintentional implicit type conversion.), then I'll do the implicit test.

Jun 18 '07 #4

P: n/a
Andre Kostur wrote:
"Victor Bazarov" <v.********@comAcast.netwrote in news:f562h2$sdg$1
@news.datemas.de:
>Zachary Turner wrote:
>>Hello,

This seems like an extremely basic question, and I'm a bit
embarassed that I can't answer it myself.

I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)

Drop the "!= 0" part and you'll have a standard construct.

Personal style: ick. I prefer to explicitly test against 0 when
dealing with ints (I also prefer to explicitly mention NULL when
dealing with pointers too.) If the expression type is bool (or 99.9%
of the time intended to be treated as a bool, such as the void*
return of streams. It's not really intended to be used as a pointer,
but it prevents other unintentional implicit type conversion.), then
I'll do the implicit test.
Yes, as a matter of style I like seeing ints tested explicitly against
zero, but for pointers I like saying 'if (pointer) '. The syntax is
also very convenient for streams (both C and C++), where you don't care
for the variable to survive beyond the point of check.

Compare

if (FILE* blah = fopen("somename", "rb")) {
// do something with 'blah'
}

and

{
FILE* blah = fopen("somename", "rb");
if (blah != NULL) {
// do something with 'blah'
}
}

Did you notice the extra pair of braces? Ick! Besides, the former
code reads better, IMNSHO. "If file opens, do something", compared
to "open blah. if blah is not NULL ..." [..Wait a minute? Why am I
checking for NULL when the term should be "opens"? so now I need to
introduce an extra utility function or macro:

inline bool opened_OK(FILE* f) { return f != NULL; }

and write

{
FILE* blah = fopen("somename", "rb");
if (opened_OK(blah)) {
// do something with 'blah'
}
}

Ick!]

See my point?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 18 '07 #5

P: n/a
"Victor Bazarov" <v.********@comAcast.netwrote in news:f56981$8c8$1
@news.datemas.de:
Andre Kostur wrote:
>"Victor Bazarov" <v.********@comAcast.netwrote in news:f562h2$sdg$1
@news.datemas.de:
>>Zachary Turner wrote:
Hello,

This seems like an extremely basic question, and I'm a bit
embarassed that I can't answer it myself.

I just recently started using GCC and tried to type the following
code:

while ((int i = getint()) != 0)

Drop the "!= 0" part and you'll have a standard construct.

Personal style: ick. I prefer to explicitly test against 0 when
dealing with ints (I also prefer to explicitly mention NULL when
dealing with pointers too.) If the expression type is bool (or 99.9%
of the time intended to be treated as a bool, such as the void*
return of streams. It's not really intended to be used as a pointer,
but it prevents other unintentional implicit type conversion.), then
I'll do the implicit test.

Yes, as a matter of style I like seeing ints tested explicitly against
zero, but for pointers I like saying 'if (pointer) '. The syntax is
also very convenient for streams (both C and C++), where you don't care
for the variable to survive beyond the point of check.

Compare

if (FILE* blah = fopen("somename", "rb")) {
// do something with 'blah'
}

and

{
FILE* blah = fopen("somename", "rb");
if (blah != NULL) {
// do something with 'blah'
}
}

Did you notice the extra pair of braces? Ick! Besides, the former
code reads better, IMNSHO. "If file opens, do something", compared
to "open blah. if blah is not NULL ..." [..Wait a minute? Why am I
checking for NULL when the term should be "opens"? so now I need to
introduce an extra utility function or macro:
Yep... but hopefully your function is small enough that the FILE* has the
scope of the entire function anyway. (Or suffer with a FILE* that has a
larger scope than strictly necessary).
inline bool opened_OK(FILE* f) { return f != NULL; }

and write

{
FILE* blah = fopen("somename", "rb");
if (opened_OK(blah)) {
// do something with 'blah'
}
}
This would be the pain of using C-style functions :) Use streams :)
>
Ick!]

See my point?
Sure... the style doesn't work for you. Arguably if you need to add
additional braces, perhaps you should consider refactoring that piece of
code into its own function.

Jun 18 '07 #6

P: n/a
Andre Kostur wrote:
"Victor Bazarov" <v.********@comAcast.netwrote in news:f56981$8c8$1
@news.datemas.de:
>Andre Kostur wrote:
>>"Victor Bazarov" <v.********@comAcast.netwrote in
news:f562h2$sdg$1 @news.datemas.de:

Zachary Turner wrote:
Hello,
>
This seems like an extremely basic question, and I'm a bit
embarassed that I can't answer it myself.
>
I just recently started using GCC and tried to type the following
code:
>
while ((int i = getint()) != 0)

Drop the "!= 0" part and you'll have a standard construct.

Personal style: ick. I prefer to explicitly test against 0 when
dealing with ints (I also prefer to explicitly mention NULL when
dealing with pointers too.) If the expression type is bool (or
99.9% of the time intended to be treated as a bool, such as the
void* return of streams. It's not really intended to be used as a
pointer, but it prevents other unintentional implicit type
conversion.), then I'll do the implicit test.

Yes, as a matter of style I like seeing ints tested explicitly
against zero, but for pointers I like saying 'if (pointer) '. The
syntax is also very convenient for streams (both C and C++), where
you don't care for the variable to survive beyond the point of check.

Compare

if (FILE* blah = fopen("somename", "rb")) {
// do something with 'blah'
}

and

{
FILE* blah = fopen("somename", "rb");
if (blah != NULL) {
// do something with 'blah'
}
}

Did you notice the extra pair of braces? Ick! Besides, the former
code reads better, IMNSHO. "If file opens, do something", compared
to "open blah. if blah is not NULL ..." [..Wait a minute? Why am I
checking for NULL when the term should be "opens"? so now I need to
introduce an extra utility function or macro:

Yep... but hopefully your function is small enough that the FILE* has
the scope of the entire function anyway. (Or suffer with a FILE*
that has a larger scope than strictly necessary).
Why suffer?
>
> inline bool opened_OK(FILE* f) { return f != NULL; }

and write

{
FILE* blah = fopen("somename", "rb");
if (opened_OK(blah)) {
// do something with 'blah'
}
}

This would be the pain of using C-style functions :) Use streams :)
Goes the same way

if (std::ifstream blah("somename", ios::binary)) {
// do something with blah
}

Works like a charm with any C++ objects that define operator void* or
operator bool to indicate "good state".
>
>>
Ick!]

See my point?

Sure... the style doesn't work for you. Arguably if you need to add
additional braces, perhaps you should consider refactoring that piece
of code into its own function.
Nope. I have a perfectly working language construct that I use instead.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 18 '07 #7

P: n/a
Thanks for the response. It appears (to no real surprise to myself)
that I'm just getting crazy in my old age. I went back and tried my
compiler which I thought accepted this and it complains as well. I
know I've declared variables in while loop parentheses hundreds if not
thousands of times, I guess I never had it parenthesized like I
thought I did. Not sure what gave me the idea to try it all of a
sudden!

Zach

On Jun 18, 8:49 am, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Zachary Turner wrote:
Hello,
This seems like an extremely basic question, and I'm a bit embarassed
that I can't answer it myself.
I just recently started using GCC and tried to type the following
code:
while ((int i = getint()) != 0)

Drop the "!= 0" part and you'll have a standard construct.
{
/* something */
}
which my compiler has been supporting for a good few years. Under GCC
this doesn't compile. At first it didn't even occur to me that maybe
the code was invalid. I just thought GCC was being stupid. But then
it occurred to me that this probably really isn't valid C++, and that
my compiler has just been breaking the rule. Can anyone shed some
light? Can you declare a variable in a while loop similar to how you
can with a for loop?

No, you cannot. Those are two different statements and they have
different syntax. You can, however, declare/define/initialise an object
in a 'while' or 'if' parentheses, but you cannot do it in an expression.

if (int i = getint())

is valid

if ((int i = getint()) != 0)

is not, although the semantics are the same. (you can replace 'if'
with 'while' above).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Jun 18 '07 #8

P: n/a
On Jun 18, 7:40 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Andre Kostur wrote:
"Victor Bazarov" <v.Abaza...@comAcast.netwrote in news:f56981$8c8$1
@news.datemas.de:
Compare
if (FILE* blah = fopen("somename", "rb")) {
// do something with 'blah'
}
and
{
FILE* blah = fopen("somename", "rb");
if (blah != NULL) {
// do something with 'blah'
}
}
Yes. The second is readable, the first isn't.
Did you notice the extra pair of braces? Ick! Besides, the former
code reads better, IMNSHO. "If file opens, do something", compared
to "open blah. if blah is not NULL ..." [..Wait a minute? Why am I
checking for NULL when the term should be "opens"? so now I need to
introduce an extra utility function or macro:
Yep... but hopefully your function is small enough that the FILE* has
the scope of the entire function anyway. (Or suffer with a FILE*
that has a larger scope than strictly necessary).
Why suffer?
Why, quite? If the function is long enough for it to make a
difference, it's too long.
This would be the pain of using C-style functions :) Use streams :)
Goes the same way

if (std::ifstream blah("somename", ios::binary)) {
// do something with blah
}
Which is just as bad?

This is a major misfeature of C++; all it leads to is unreadable
code.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 18 '07 #9

P: n/a
James Kanze wrote:
[.. style differences identified ..]
This is a major misfeature of C++; all it leads to is unreadable
code.
Readability of the code is NOT an objective characteristic, we
should abandon this religious debate right here. Deal?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 18 '07 #10

P: n/a
"Victor Bazarov" <v.********@comAcast.netwrote in news:f56oqb$42v$1
@news.datemas.de:
James Kanze wrote:
>[.. style differences identified ..]
This is a major misfeature of C++; all it leads to is unreadable
code.

Readability of the code is NOT an objective characteristic, we
should abandon this religious debate right here. Deal?
Kinda why I stopped... this is all up to personal preference. I like my
way, you like yours, we're not hurting each other....
Jun 18 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.