Discussion:
Initialization within for loop
(too old to reply)
Alla _
2015-12-18 12:10:53 UTC
Permalink
Hello!

I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.

If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?

Here is an example. The job is done by the while loop within get_line function,
and I would like to achieve the same result with the for loop, for educational
purpose merely. Obviously, I can't omit the initialization.

for (???; isspace(s[i]); i--)
;

Test program:
#include <stdio.h>
#include <ctype.h>

int main(void)
{
char line[1000] = {0};
int length = get_line(line, 1000);

printf("%i: %s\n", length, line);

return 0;
}

/* getline: read a line into s, return length */

int get_line (char s[], int lim)
{
int c;
int len;
int i = 0;

while ((c = getchar()) != EOF && isspace(c))
;
s[i] = c;

for (i = 1; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++)
{
s[i] = c;
}

if (c == '\n')
{
s[i] = c;
}
/* skip trailling spaces */

while (isspace(s[i])) /* here I would like to use the for loop */
{
i--;
}
/* for (???; isspace(s[i]); i--)
;
*/
len = ++i;
s[i++] = '\n';
s[i] = '\0';

return len;
}

Thank you!
Malcolm McLean
2015-12-18 12:22:32 UTC
Permalink
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
int i = 42;

for(;i<N;i++)

but don't write C like that. You should never have an empty statement in a for
loop. Use while instead

while(i<N)
{
/* body */
i++;
}
Alla _
2015-12-18 12:31:38 UTC
Permalink
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
I see that you have assigned value to i (this is a clear method), but in my
case i is being computed by the program.
Ben Bacarisse
2015-12-18 12:57:09 UTC
Permalink
Post by Alla _
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this
variable has acquired some value, and after that I would like to
use a for loop that starts from the last available value of i, how
do I put that value in the for loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement
in a for loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
Yes, a while loop is good solution, but please feel free to ignore
Malcolm's advice -- the firmness of its delivery is not correlated to
how widely held it is, not with the quantity of evidence in support of
it (so far as I know).

Omitting one of the parts of a for loop should make you stop and think.
Is this really the best way to write what I mean? In C99, which has
scope-limited declaration in the first clause, I'd consider writing:

for (int j = i; j < N; j++)
// use j here instead

About the only clause of the three that I *would* consider omitting is the
first. Omitting the second is a bit mysterious (it defaults to 1) and
it's the last (the "step" stage) that make a for loop a for loop, but
there are cases where I might think it's neater to leave off the first.

<snip>
--
Ben.
Alla _
2015-12-18 15:21:38 UTC
Permalink
Post by Ben Bacarisse
Post by Alla _
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this
variable has acquired some value, and after that I would like to
use a for loop that starts from the last available value of i, how
do I put that value in the for loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement
in a for loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
Yes, a while loop is good solution, but please feel free to ignore
Malcolm's advice -- the firmness of its delivery is not correlated to
how widely held it is, not with the quantity of evidence in support of
it (so far as I know).
Omitting one of the parts of a for loop should make you stop and think.
Is this really the best way to write what I mean? In C99, which has
for (int j = i; j < N; j++)
// use j here instead
Thank you ) Of course - a new variable is a tool at hand.
Barry Schwarz
2015-12-18 15:53:24 UTC
Permalink
On Fri, 18 Dec 2015 12:57:09 +0000, Ben Bacarisse
Post by Ben Bacarisse
Post by Alla _
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this
variable has acquired some value, and after that I would like to
use a for loop that starts from the last available value of i, how
do I put that value in the for loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement
in a for loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
Yes, a while loop is good solution, but please feel free to ignore
Malcolm's advice -- the firmness of its delivery is not correlated to
how widely held it is, not with the quantity of evidence in support of
it (so far as I know).
Omitting one of the parts of a for loop should make you stop and think.
Is this really the best way to write what I mean? In C99, which has
for (int j = i; j < N; j++)
// use j here instead
That's works only when the program is not expecting i to contain an
updated value after the loop terminates.
--
Remove del for email
Ken Brody
2015-12-21 17:37:12 UTC
Permalink
Post by Barry Schwarz
On Fri, 18 Dec 2015 12:57:09 +0000, Ben Bacarisse
[...]
Post by Barry Schwarz
Post by Ben Bacarisse
Post by Alla _
If the program has a variable i, which is an array index, and this
variable has acquired some value, and after that I would like to
use a for loop that starts from the last available value of i, how
do I put that value in the for loop?
[...]
Post by Barry Schwarz
Post by Ben Bacarisse
Omitting one of the parts of a for loop should make you stop and think.
Is this really the best way to write what I mean? In C99, which has
for (int j = i; j < N; j++)
// use j here instead
That's works only when the program is not expecting i to contain an
updated value after the loop terminates.
Not to mention the concept of:

int i=0;

...

for ( ; i < N && condition_1 ; i++ )
{
... do stuff ...
}
for ( ; i < N && condition_2 ; i++ )
{
... do more stuff ...
}
for ( ; i < N && condition_3 ; i++ )
{
... do other stuff ...
}

...

I would only create a new variable when the following code expects 'i' to
have its "original" value.

If the following code never uses 'i' again, I'd still call the "int j=i"
method "useless creation of a new variable".
--
Kenneth Brody
Jerry Stuckle
2015-12-18 14:35:21 UTC
Permalink
Post by Alla _
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
I see that you have assigned value to i (this is a clear method), but in my
case i is being computed by the program.
Yes, a while loop is a good way to do it. But it's not at all uncommon
to drop one (or more) parts of a for loop. For instance, it's not at
all unusual to see something like

for (;;)

An infinite loop, which breaks out somewhere in the loop. Sure, you can
also use

while (1)

to do the same thing, and some people think it's clearer. But it's all
a matter of style. If you're working with a group, you need to adapt
to their style. If you're on your own, you should develop a style and
use it consistently. It will save you a lot of head scratching down the
road when you need to come back and look at old code.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Keith Thompson
2015-12-18 16:49:23 UTC
Permalink
Jerry Stuckle <***@attglobal.net> writes:
[...]
Post by Jerry Stuckle
Yes, a while loop is a good way to do it. But it's not at all uncommon
to drop one (or more) parts of a for loop. For instance, it's not at
all unusual to see something like
for (;;)
An infinite loop, which breaks out somewhere in the loop. Sure, you can
also use
while (1)
to do the same thing, and some people think it's clearer. But it's all
a matter of style. If you're working with a group, you need to adapt
to their style. If you're on your own, you should develop a style and
use it consistently. It will save you a lot of head scratching down the
road when you need to come back and look at old code.
It may not be *just* a matter of style. I've seen compilers warn about
`while (1)` because the condition being tested is always true, but not
warn about `for (;;)` because there's no explicit condition for the
compiler to warn about. Of course they're semantically equivalent, and
both reasonably clear and common usage, so a compiler *shouldn't*
--
Keith Thompson (The_Other_Keith) kst-***@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jerry Stuckle
2015-12-18 18:01:34 UTC
Permalink
Post by Keith Thompson
[...]
Post by Jerry Stuckle
Yes, a while loop is a good way to do it. But it's not at all uncommon
to drop one (or more) parts of a for loop. For instance, it's not at
all unusual to see something like
for (;;)
An infinite loop, which breaks out somewhere in the loop. Sure, you can
also use
while (1)
to do the same thing, and some people think it's clearer. But it's all
a matter of style. If you're working with a group, you need to adapt
to their style. If you're on your own, you should develop a style and
use it consistently. It will save you a lot of head scratching down the
road when you need to come back and look at old code.
It may not be *just* a matter of style. I've seen compilers warn about
`while (1)` because the condition being tested is always true, but not
warn about `for (;;)` because there's no explicit condition for the
compiler to warn about. Of course they're semantically equivalent, and
both reasonably clear and common usage, so a compiler *shouldn't*
True, but then they could also warn about 'for (;;;)' - I've seen some
versions of LINT do that in the past.

It's just really hard to get a compiler to provide warnings when you
screw up, yet not warn on intentional constructs :)
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Richard Heathfield
2015-12-18 18:02:48 UTC
Permalink
<snip>
Post by Jerry Stuckle
Post by Keith Thompson
It may not be *just* a matter of style. I've seen compilers warn about
`while (1)` because the condition being tested is always true, but not
warn about `for (;;)` because there's no explicit condition for the
compiler to warn about. Of course they're semantically equivalent, and
both reasonably clear and common usage, so a compiler *shouldn't*
True, but then they could also warn about 'for (;;;)
The compiler is *required* to warn about that, because it's a syntax
error. You meant for(;;) but yes, you are correct that a compiler may
issue any diagnostic message it likes at any time for any code.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Jerry Stuckle
2015-12-18 19:30:29 UTC
Permalink
Post by Ben Bacarisse
<snip>
Post by Jerry Stuckle
Post by Keith Thompson
It may not be *just* a matter of style. I've seen compilers warn about
`while (1)` because the condition being tested is always true, but not
warn about `for (;;)` because there's no explicit condition for the
compiler to warn about. Of course they're semantically equivalent, and
both reasonably clear and common usage, so a compiler *shouldn't*
True, but then they could also warn about 'for (;;;)
The compiler is *required* to warn about that, because it's a syntax
error. You meant for(;;) but yes, you are correct that a compiler may
issue any diagnostic message it likes at any time for any code.
Sorry - my ';' key got stuck :)
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Stephen Sprunk
2015-12-21 20:41:29 UTC
Permalink
Post by Keith Thompson
Post by Jerry Stuckle
Yes, a while loop is a good way to do it. But it's not at all
uncommon to drop one (or more) parts of a for loop. For instance,
it's not at all unusual to see something like
for (;;)
An infinite loop, which breaks out somewhere in the loop. Sure,
you can also use
while (1)
to do the same thing, and some people think it's clearer. But it's
all a matter of style. ...
It may not be *just* a matter of style. I've seen compilers warn
about `while (1)` because the condition being tested is always true,
but not warn about `for (;;)` because there's no explicit condition
for the compiler to warn about. Of course they're semantically
equivalent, and both reasonably clear and common usage, so a compiler
*shouldn't*
Both are common idioms, as is "if(1)", and every compiler I've used has
logic to _not_ warn for them because they're clearly intentional; ditto
for "while(0)" and "if(0)".

More interesting is when optimizations reduce complicated expressions to
an always-true (or always-false) condition at compile time that may NOT
have been intentional. Warnings in such cases can be unpredictable.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
Richard Bos
2015-12-21 21:38:03 UTC
Permalink
Post by Stephen Sprunk
Both are common idioms, as is "if(1)", and every compiler I've used has
logic to _not_ warn for them because they're clearly intentional; ditto
for "while(0)" and "if(0)".
More interesting is when optimizations reduce complicated expressions to
an always-true (or always-false) condition at compile time that may NOT
have been intentional. Warnings in such cases can be unpredictable.
And then there are the cases where the controlling expression uses
macros and depends on conditional compilation, for example for
platform-specific code.

Richard
Barry Schwarz
2015-12-18 15:50:50 UTC
Permalink
On Fri, 18 Dec 2015 04:31:38 -0800 (PST), Alla _
Post by Alla _
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop. Use while instead
while(i<N)
{
/* body */
i++;
}
Thank you. I see that it's better to use while loop, as I actually did.
I see that you have assigned value to i (this is a clear method), but in my
case i is being computed by the program.
After your program calculates the value of i, how does that value get
stored in i? Surely i appears on the left of an assignment operator.
You even said it in your question: "this variable has acquired some
value." Did that not involve an assignment?

All Malcolm did (thank you for remembering the attribution) was
provide a sample so that nitpickers would not comment that i was
indeterminate.

Whether while loop is better than an empty for clause is a style
question. Either answers the question you asked.
--
Remove del for email
Richard Heathfield
2015-12-18 15:29:09 UTC
Permalink
Post by Malcolm McLean
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop.
Why?
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Malcolm McLean
2015-12-18 15:49:39 UTC
Permalink
Post by Malcolm McLean
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop.
Why?
Because any programmer, from any background, with just a bit of experience, can
read

for(i=0;i<N;i++)

and know exactly what it means.

for(;i<N;i++)

is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Richard Heathfield
2015-12-18 16:04:57 UTC
Permalink
Post by Malcolm McLean
Post by Malcolm McLean
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop.
Why?
Because any programmer, from any background, with just a bit of experience, can
read
for(i=0;i<N;i++)
and know exactly what it means.
for(;i<N;i++)
is a head scratcher.
Why?
Post by Malcolm McLean
Not if you know C,
Right. And if you don't know C, you shouldn't be maintaining my code.

I'm all for making code as readable as possible, but I don't see the
need to make it Janet-and-John.
Post by Malcolm McLean
but even then, it puts a burden on the reader.
Hardly.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Malcolm McLean
2015-12-18 16:15:31 UTC
Permalink
Post by Richard Heathfield
Right. And if you don't know C, you shouldn't be maintaining my code.
I'm all for making code as readable as possible, but I don't see the
need to make it Janet-and-John.
My current code will be maintained by C++ programmers.
But the stuff I wrote for my PhD was likely to be used by Fortran 77 programmers.
The physics community is like that - these are people who know a lot about
energy equations (drop the term "Hessian" into your conversation to pass yourself
off) but not much about programming computers. I found a brute force selection
sort in a time critical part of someone's code, for example.
BartC
2015-12-18 16:30:30 UTC
Permalink
Post by Malcolm McLean
Post by Malcolm McLean
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement in a for
loop.
Why?
Because any programmer, from any background, with just a bit of experience, can
read
for(i=0;i<N;i++)
and know exactly what it means.
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it
will have that same value by the time it gets to the loop. And if you
can't find it, you have to start analysing the code to find out what i
might be.

It's extra effort too, if you want to lift such a for-loop from one
piece of code to another; it' not self-contained.
--
Bartc
Jerry Stuckle
2015-12-18 16:49:39 UTC
Permalink
Post by BartC
Post by Malcolm McLean
Post by Malcolm McLean
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty
statement in a for
loop.
Why?
Because any programmer, from any background, with just a bit of experience, can
read
for(i=0;i<N;i++)
and know exactly what it means.
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it
will have that same value by the time it gets to the loop. And if you
can't find it, you have to start analysing the code to find out what i
might be.
Which is no different than any other loop where i already has the
initial value, such as the other option he gave:

while(i<N)
{
/* body */
i++;
}

Not all loops are self-contained. And not all loops start at the
beginning of a string/array/whatever.
Post by BartC
It's extra effort too, if you want to lift such a for-loop from one
piece of code to another; it' not self-contained.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
BartC
2015-12-18 19:00:52 UTC
Permalink
Post by Jerry Stuckle
Post by BartC
Post by Malcolm McLean
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it
will have that same value by the time it gets to the loop. And if you
can't find it, you have to start analysing the code to find out what i
might be.
Which is no different than any other loop where i already has the
while(i<N)
{
/* body */
i++;
}
It depends on the code pattern. You would hope that here, i is
initialised just before the loop. But in that case, there's no reason to
write:

i=0; // or whatever
for (; i<N; ++i)

instead of:

for (i=0; i<N; ++i)

This would follow a very common pattern but you will see that
immediately. But presented with:

for (; i<N; ++i)

and a remote initialisation, there is a possibility of a more unusual
Post by Jerry Stuckle
Not all loops are self-contained. And not all loops start at the
beginning of a string/array/whatever.
--
Bartc
Jerry Stuckle
2015-12-18 19:32:16 UTC
Permalink
Post by BartC
Post by Jerry Stuckle
Post by BartC
Post by Malcolm McLean
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a
burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it
will have that same value by the time it gets to the loop. And if you
can't find it, you have to start analysing the code to find out what i
might be.
Which is no different than any other loop where i already has the
while(i<N)
{
/* body */
i++;
}
It depends on the code pattern. You would hope that here, i is
initialised just before the loop. But in that case, there's no reason to
i=0; // or whatever
for (; i<N; ++i)
for (i=0; i<N; ++i)
Which is NOT the case in the code the OP asked about.
Post by BartC
This would follow a very common pattern but you will see that
for (; i<N; ++i)
and a remote initialisation, there is a possibility of a more unusual
Anything is possible if the programmer is sloppy.
Post by BartC
Post by Jerry Stuckle
Not all loops are self-contained. And not all loops start at the
beginning of a string/array/whatever.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Ken Brody
2015-12-21 17:46:34 UTC
Permalink
[...]
Post by BartC
Post by Malcolm McLean
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it will
have that same value by the time it gets to the loop. And if you can't find
it, you have to start analysing the code to find out what i might be.
Maybe the value of 'i' was determined to be one of several values?

if ( condition_1 )
i = some_function();
else if ( condition_2 )
i = some_other_function();
else
i = 0;

for ( ; i < N ; i++ )
{
...
}
Post by BartC
It's extra effort too, if you want to lift such a for-loop from one piece of
code to another; it' not self-contained.
The loop requires that 'i' be already initialized. Unless that other piece
of code is to initialize 'i' the same way, you couldn't just cut-and-paste
anyway.

Even using someone else's suggestion of:

for ( int j=i ; j < N ; j++ )
{
...
}

still has whatever "burden" in finding the initial value.
--
Kenneth Brody
Stephen Sprunk
2015-12-21 20:04:56 UTC
Permalink
Post by Ken Brody
Post by BartC
It's extra effort too, if you want to lift such a for-loop from
one piece of code to another; it' not self-contained.
The loop requires that 'i' be already initialized. Unless that
other piece of code is to initialize 'i' the same way, you couldn't
just cut-and-paste anyway.
for ( int j=i ; j < N ; j++ ) { ... }
still has whatever "burden" in finding the initial value.
Agreed, but that doesn't seem to have the same headscratch-inducing
quality. Maybe it's because the uninitialized version looks like it
could be accidental, whereas this version is obviously deliberate?

Also, I'd expect "i" to be a more descriptive name and the loop itself
to be "i"; conventionally, "j" loops are only nested within "i" loops,
and any other variable gets a real name.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
BartC
2015-12-21 20:24:52 UTC
Permalink
Post by Ken Brody
[...]
Post by BartC
Post by Malcolm McLean
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden on the reader.
Yes, the burden is that you have to go and hunt for what might be the
initial value of i. And when you've found it, you have to check that it will
have that same value by the time it gets to the loop. And if you can't find
it, you have to start analysing the code to find out what i might be.
Maybe the value of 'i' was determined to be one of several values?
if ( condition_1 )
i = some_function();
else if ( condition_2 )
i = some_other_function();
else
i = 0;
for ( ; i < N ; i++ )
{
...
}
Then maybe there is an excuse for it. But not if i starts from 0 but
this piece of information is omitted; is this a bog-standard for loop or
something special like your example?
Post by Ken Brody
Post by BartC
It's extra effort too, if you want to lift such a for-loop from one piece of
code to another; it' not self-contained.
The loop requires that 'i' be already initialized. Unless that other
piece of code is to initialize 'i' the same way, you couldn't just
cut-and-paste anyway.
for ( int j=i ; j < N ; j++ )
{
...
}
still has whatever "burden" in finding the initial value.
The initial value is i...

Here at least, you know at a glance that is a slightly different kind of
loop.
--
Bartc
Kenny McCormack
2015-12-18 16:31:45 UTC
Permalink
Post by Malcolm McLean
Post by Malcolm McLean
int i = 42;
for(;i<N;i++)
but don't write C like that. You should never have an empty statement
in a for loop.
Why?
Because any programmer, from any background, with just a bit of
experience, can read
for(i=0;i<N;i++)
and know exactly what it means.
for(;i<N;i++)
is a head scratcher. Not if you know C, but even then, it puts a burden
on the reader.
While the idea that you should produce your C code in a style that can be
read by non-C-programmers actually does have a certain amount of cred,
especially in your sort of situation where Fortran is really the lingua
franca (which suggests, incidentally, that you should not have done your
part in C or C++ in the first place), it [*] is, and always will be, a hard
sell in this newsgroup, comp.lang.c.

[*] "It" being the idea that any old programmer should be able to read your
C code.
--
Shikata ga nai...
Richard Heathfield
2015-12-18 15:32:10 UTC
Permalink
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
Here is an example. The job is done by the while loop within get_line function,
and I would like to achieve the same result with the for loop, for educational
purpose merely. Obviously, I can't omit the initialization.
Why not?
Post by Alla _
for (???; isspace(s[i]); i--)
for( ; isspace(s[i]); i--)

But be careful - you might run off the beginning of the array, which
would be bad. Assuming i is signed, you could do:

for( ; i >=0 && isspace(s[i]); i--)
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
Alla _
2015-12-18 16:48:58 UTC
Permalink
Post by Richard Heathfield
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
Here is an example. The job is done by the while loop within get_line function,
and I would like to achieve the same result with the for loop, for educational
purpose merely. Obviously, I can't omit the initialization.
Why not?
Post by Alla _
for (???; isspace(s[i]); i--)
for( ; isspace(s[i]); i--)
But be careful - you might run off the beginning of the array, which
for( ; i >=0 && isspace(s[i]); i--)
My goal was to skip all spaces and stop at the first non-space character.
I have tried many times this for( ; isspace(s[i]); i--) and it didn't work out.
Interesting.
Initially, I thought that if I don't initialize i within for loop, the loop
would take whatever value i has at the moment the loop starts. Therefore, I
have put for( ; isspace(s[i]); i--), and as I said it didn't work.
Jerry Stuckle
2015-12-18 18:05:14 UTC
Permalink
Post by Alla _
Post by Richard Heathfield
Post by Alla _
Hello!
I have a technical question, and I failed to google it correctly, therefore
was unable to get answer from the web.
If the program has a variable i, which is an array index, and this variable
has acquired some value, and after that I would like to use a for loop that
starts from the last available value of i, how do I put that value in the for
loop?
Here is an example. The job is done by the while loop within get_line function,
and I would like to achieve the same result with the for loop, for educational
purpose merely. Obviously, I can't omit the initialization.
Why not?
Post by Alla _
for (???; isspace(s[i]); i--)
for( ; isspace(s[i]); i--)
But be careful - you might run off the beginning of the array, which
for( ; i >=0 && isspace(s[i]); i--)
My goal was to skip all spaces and stop at the first non-space character.
I have tried many times this for( ; isspace(s[i]); i--) and it didn't work out.
Interesting.
Initially, I thought that if I don't initialize i within for loop, the loop
would take whatever value i has at the moment the loop starts. Therefore, I
have put for( ; isspace(s[i]); i--), and as I said it didn't work.
And it should do that, if i is initialized to a point past the beginning
of the string before entering the loop.

Richard brought up another point - you don't want to go beyond the
beginning of the string, which could also be causing you a problem.
--
==================
Remove the "x" from my email address
Jerry Stuckle
***@attglobal.net
==================
Barry Schwarz
2015-12-18 19:24:46 UTC
Permalink
On Fri, 18 Dec 2015 08:48:58 -0800 (PST), Alla _
Post by Alla _
My goal was to skip all spaces and stop at the first non-space character.
I have tried many times this for( ; isspace(s[i]); i--) and it didn't work out.
Interesting.
Initially, I thought that if I don't initialize i within for loop, the loop
would take whatever value i has at the moment the loop starts. Therefore, I
have put for( ; isspace(s[i]); i--), and as I said it didn't work.
Then your problem was somewhere else in the code or in an unfounded
assumption.
--
Remove del for email
Ken Brody
2015-12-21 17:58:42 UTC
Permalink
On 12/18/2015 11:48 AM, Alla _ wrote:
[...]
Post by Alla _
Post by Richard Heathfield
for( ; i >=0 && isspace(s[i]); i--)
My goal was to skip all spaces and stop at the first non-space character.
I have tried many times this for( ; isspace(s[i]); i--) and it didn't work out.
Interesting.
Initially, I thought that if I don't initialize i within for loop, the loop
would take whatever value i has at the moment the loop starts.
If you don't assign a specific value to 'i' in the 'for' initialization,
then 'i' *does* hold whatever it had prior to the for-loop. (Variables
don't magically change value just because you didn't assign a value to them.)

Side question:

Given the following code:

int i;
int j=i;
int k=i;

if ( j != k )
{
printf("I have no idea how I got here!\n");
}

Could a confirming implementation have different values for j and k?
Or does the mere fact that using the uninitialized 'i' in the first
place mean that it's value is allowed to change up until the point
that it's initialized?
Post by Alla _
Therefore, I
have put for( ; isspace(s[i]); i--), and as I said it didn't work.
Define "didn't work". Aside from the possibility of falling off the
beginning of the array it it's all spaces, what "didn't work" with your version?
--
Kenneth Brody
James Kuyper
2015-12-21 18:32:38 UTC
Permalink
Post by Ken Brody
[...]
Post by Alla _
Post by Richard Heathfield
for( ; i >=0 && isspace(s[i]); i--)
My goal was to skip all spaces and stop at the first non-space character.
I have tried many times this for( ; isspace(s[i]); i--) and it didn't work out.
Interesting.
Initially, I thought that if I don't initialize i within for loop, the loop
would take whatever value i has at the moment the loop starts.
If you don't assign a specific value to 'i' in the 'for' initialization,
then 'i' *does* hold whatever it had prior to the for-loop. (Variables
don't magically change value just because you didn't assign a value to them.)
int i;
int j=i;
int k=i;
if ( j != k )
{
printf("I have no idea how I got here!\n");
}
Could a confirming implementation have different values for j and k?
Yes. The C committee resolved a Defect Report (I don't remember the
number) by confirming that if something is unspecified, then the
implementation can make a different choice from among the permitted
possibilities each time the issue comes up - it could change between one
piece of code and the next, or even between consecutive executions of
the same piece of code.

I think there's a exception (possibly implicit rather than explicit) for
some things that would be unusable if they were subject to change. For
instance, "Many aspects of the representation of types" are unspecified,
and C would be essentially useless if those aspects were not the same in
every translation unit of a program, and for the entire time that a
program is running. However, the unspecified value of an uninitialized
variable is NOT one of the things you're supposed to use, so rendering
it unusable is not a problem.

Once a value is stored in an object, the program must always behave as
thought it retained it's last-stored value (6.2.4p2). As long as the
code has defined behavior, the as-if rule is the only way this
requirement can be evaded. However, until the first time that a value is
written to 'i', 6.2.4p2 imposes no requirements on the value read.

As a practical matter, that means that the memory that will eventually
be reserved solely for the purpose of storing the value of 'i' can,
until the first write to 'i', be used for some other purpose as well.
That other purpose might cause it's unspecified value to change between
consecutive reads. That's unlikely to happen in code this simple, but if
you (or the optimizer) put any significant amount of code between the
initialization of j and the initialization of k, the memory that will
eventually be reserved solely for use as the variable 'i' might
represent a different value for those two initializations.
s***@casperkitty.com
2015-12-21 19:36:41 UTC
Permalink
Given code like:

uint16_t foo(uint32_t x)
{
uint16_t y;
if (x < 4000) y=x;
return y;
}
uint32_t bar(uint32_t x)
{
return foo(x);
}

it would not be uncommon, regardless of what the Standard says, for function
bar() to yield a value outside the range 0-65535 when passed an over-sized
value of x. Compilers often use 32-bit registers to hold 16-bit values;
if storing that could legally exceed 65535 is stored into such a register,
compilers will ensure the value gets truncated, but if something should be a
16-bit value many compilers will skip the truncation step. I don't know that
such behavior is compliant with C89 or C99 rules, but I've observed such
behavior in a number of real-world compilers.
Stephen Sprunk
2015-12-21 20:15:08 UTC
Permalink
Post by s***@casperkitty.com
uint16_t foo(uint32_t x)
{
uint16_t y;
if (x < 4000) y=x;
return y;
}
uint32_t bar(uint32_t x)
{
return foo(x);
}
it would not be uncommon, regardless of what the Standard says, for
function bar() to yield a value outside the range 0-65535 when passed
an over-sized value of x. Compilers often use 32-bit registers to
hold 16-bit values; if storing that could legally exceed 65535 is
stored into such a register, compilers will ensure the value gets
truncated, but if something should be a 16-bit value many compilers
will skip the truncation step. I don't know that such behavior is
compliant with C89 or C99 rules, but I've observed such behavior in a
number of real-world compilers.
If x>=4000, then the behavior of return y; is undefined, and the
compiler is allowed to do whatever it wants in that case, including
acting as if it returned a value outside the type's actual range.

S
--
Stephen Sprunk "God does not play dice." --Albert Einstein
CCIE #3723 "God is an inveterate gambler, and He throws the
K5SSS dice at every possible opportunity." --Stephen Hawking
BartC
2015-12-21 20:20:36 UTC
Permalink
Post by s***@casperkitty.com
uint16_t foo(uint32_t x)
{
uint16_t y;
if (x < 4000) y=x;
return y;
}
uint32_t bar(uint32_t x)
{
return foo(x);
}
it would not be uncommon, regardless of what the Standard says, for function
bar() to yield a value outside the range 0-65535 when passed an over-sized
value of x. Compilers often use 32-bit registers to hold 16-bit values;
if storing that could legally exceed 65535 is stored into such a register,
compilers will ensure the value gets truncated, but if something should be a
16-bit value many compilers will skip the truncation step. I don't know that
such behavior is compliant with C89 or C99 rules, but I've observed such
behavior in a number of real-world compilers.
Which compilers do that?

The return from foo() is 16 bits and would need to be zero-extended to
32. Unless the compiler can deduce out that the top 16 bits will already
be zero.

Anyway if the natural int size is 32-bits, you would expect widening to
occur everywhere that 16-bit values are used:

uint16_t x,y;
int a;

x=40000;
y=50000;

a=x+y;

printf("%d\n",a);

This prints 90000, not 24464, as does printf("%d\n",x+y);
--
Bartc
Richard Bos
2016-01-16 16:32:44 UTC
Permalink
Post by s***@casperkitty.com
uint16_t foo(uint32_t x)
{
uint16_t y;
if (x < 4000) y=x;
return y;
}
uint32_t bar(uint32_t x)
{
return foo(x);
}
it would not be uncommon, regardless of what the Standard says, for function
bar() to yield a value outside the range 0-65535 when passed an over-sized
value of x.
It may not be uncommon - I wouldn't know, I've never written such
accidentally-correct-but-conceptually-broken code - but that doesn't
make it conforming, or right.
Nevertheless, the _intent_ of this code is clearly wrong, so regardless
of its official status, I would no more use it than code which relies on
"what everybody knows" implementations _do_ unconformingly allow.

Richard
James Kuyper
2016-01-16 17:08:52 UTC
Permalink
Post by Richard Bos
Post by s***@casperkitty.com
uint16_t foo(uint32_t x)
{
uint16_t y;
if (x < 4000) y=x;
return y;
}
uint32_t bar(uint32_t x)
{
return foo(x);
}
it would not be uncommon, regardless of what the Standard says, for function
bar() to yield a value outside the range 0-65535 when passed an over-sized
value of x.
It may not be uncommon - I wouldn't know, I've never written such
accidentally-correct-but-conceptually-broken code - but that doesn't
make it conforming, or right.
Nevertheless, the _intent_ of this code is clearly wrong, so regardless
of its official status, I would no more use it than code which relies on
"what everybody knows" implementations _do_ unconformingly allow.
I agree with your "conceptually broken" evaluation. However, I'm
confused about the "what everybody knows" part. As I understand it, a
conforming implementation of C implement foo() in a way that gives 'y'
an unspecified but valid uint16_t value. If x<4000, foo() must return x,
otherwise it must return the unspecified value of y - but either way
foo()'s return value must be in the range 0-65535. bar() is required to
convert that value from uint16_t to uint32_t, a conversion that cannot
change the value being converted. The code is not strictly conforming,
but it doesn't have any syntax errors or constraint violations
If I'm correct, any implementation that does what
***@casperkitty.com says is non-conforming. There's nothing unusual
about non-conforming implementations, but I'm curious about precisely
how and why they fail to conform. I can't imagine any reason why an
implementation would translate this code to do anything other than what
I've explained above.

Loading...