setting to zero

S

Seebs

I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be zero.

No, you're getting a huge number when it should be undefined behavior.
#include <stdio.h>
#define __STRICT_ANSI__
int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];

This loop is almost certainly wrong. Why are you checking "k < 4" rather than
"j < 4"?

But wait, also, i[] is uninitialized.

So.

First, you are iterating through i, adding uninitialized values. You could
get anything.

Secondly, if it happens that j is physically after i, then even if i is all
set to 0s, you will eventually set j to 4. k will still be zero, so you'll
enter the loop, and set k = k + i[4], and i[4] in that case would be j, which
happens to be 4.

But that's speculative, and different machines will give different results.
In general, you have no legitimate expectation of ANYTHING coherent happening.

To fix this:

1. Use "j < 4" as your loop control.
2. Use i[4] = {0} as the initializer. (Elements in the array past those
initialized explicitly will be zero, but this is true only if there is at
least SOME initializer.)

-s
 
C

Chris M. Thomasson

[...]
I know in this case a simple alternative would be

int i[4]={0,0,0,0};

And that's fine but what if it were int i[128]; ?

You don't have to set each individual `int' in the array to zero. This is
fine:


int i[4] = { 0 };


Anyway, you're improperly accessing the `i' array beyond it's boundary. Try
something like this:
____________________________________________________
#include <stdio.h>


int main(void)
{
int i[4] = { 0 }, j = 0, k = 0;

for (; j < 4; ++j) k += i[j];

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

return 0;
}

____________________________________________________




BTW, do you work for Microsoft?
 
P

Peter Nilsson

This is as useful/useless as...

#define WICKER_BASKETS
int main(void)
{
   int i[4], j, k;
   k = 0;
   for (j = 0; k < 4; ++j)
       k = k + i[j];
   printf("%d\n", k);
}

    I know in this case a simple alternative would be

int i[4]={0,0,0,0};

And that's fine but what if it were int i[128]; ?

int i[128] = { 0 };

If there is an initialiser, then aggregate elements that are
not explicitly initialised will be zero initialised by default.
 
C

chad

Bill said:
    I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be zero.
#include <stdio.h>
#define __STRICT_ANSI__
int main(void)
{
    int i[4], j, k;
    k = 0;
    for (j = 0; k < 4; ++j)
        k = k + i[j];
    printf("%d\n", k);
}
I'm not getting any errors and it compiles fine. Just not the right result.

Hi Bill. What do you think i[j] is?

I guess I'm not seeing what i[j] is either. I've noticed Bill makes
this mistake a lot. However, I just don't see his possible line of
reasoning in doing something like i[j].

Chad
 
K

Keith Thompson

PN> This is as useful/useless as...
PN>
PN> #define WICKER_BASKETS
Why does that macro exist? I thought it might be better than -std=c89 or
whatever gcc switch is used.

I've added a PN prefix to each line you quoted from Peter Nilsson's
article, since they weren't properly marked in your followup.

Find a way to quote properly. Do it manually if you have to, or
install OE-QuoteFix (Google it), or use a different newsreader.
Do this before posting again.

Ok, I just checked the gcc documentation. Apparently the "-ansi"
option cause the macro __STRICT_ANSI__ to be predefined, and some
header files pay attention to it. (You posted code that uses it,
but you didn't mention that it's gcc-specific.)

Don't define it yourself; just use the proper command-line options.
 
K

Keith Thompson

Bill Cunningham said:
I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be zero.

#include <stdio.h>
#define __STRICT_ANSI__

int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];
printf("%d\n", k);
}

I'm not getting any errors and it compiles fine. Just not the right result.

Use better names for your variables. The name "i" is commonly used
for a loop index; you're using it for an array, which makes your code
more difficult to read. "j" and "k" are sometimes used secondary loop
indices; "j" is ok, but you're using "k" as a sum.

Here's a version of your program with better names for the variables
and no other changes. I've left all your errors in place. It should
now be easier to see at least some of them.

#include <stdio.h>
#define __STRICT_ANSI__

int main(void)
{
int arr[4], i, sum;
sum = 0;
for (i = 0; sum < 4; ++i)
sum = sum + arr;
printf("%d\n", sum);
}
 
B

Bill Cunningham

I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be zero.

#include <stdio.h>
#define __STRICT_ANSI__

int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];
printf("%d\n", k);
}

I'm not getting any errors and it compiles fine. Just not the right result.

Bill
 
B

Bill Cunningham

Bill Cunningham said:
I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be
zero.

#include <stdio.h>
#define __STRICT_ANSI__

int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];
printf("%d\n", k);
}

I'm not getting any errors and it compiles fine. Just not the right
result.

Bill

I know in this case a simple alternative would be

int i[4]={0,0,0,0};

And that's fine but what if it were int i[128]; ?

Bill
 
B

Bill Cunningham

If there is an initialiser, then aggregate elements that are
not explicitly initialised will be zero initialised by default.

Ok I didn't know that. Probably should've but didn't.

Bill
 
B

Bill Cunningham

This is as useful/useless as...

#define WICKER_BASKETS

Why does that macro exist? I thought it might be better than -std=c89 or
whatever gcc switch is used.

Bill
 
M

Morris Keesan

I should know how to do this. I've done it before but I'm just not
getting the right result. I'm getting a huge number when it should be
zero.

#include <stdio.h>
#define __STRICT_ANSI__

int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];
printf("%d\n", k);
}

Contrary to the subject line, nothing in this code sets anything to zero,
except the "k = 0" statement, and the "j = 0" initializer for the for loop.
variables local to a function (formally, variables with "automatic"
storage)
don't get initialized to anything.
 
M

Morris Keesan

int i[4] = { 0 }, j = 0, k = 0;
for (; j < 4; ++j)

Yuck. I know some people believe that everything should always be
initialized
where declared, but do you really think it improves the code to remove the
j = 0 initializer in the for loop? For me, this drastically degrades the
readability, because I have to start searching through the code to find out
what the values of the variables are at the start of the loop. Even though
in this case the initialization is in the previous line, I still needed to
do some searching to find that it had been initialized.
 
C

Chris M. Thomasson

Morris Keesan said:
int i[4] = { 0 }, j = 0, k = 0;
for (; j < 4; ++j)

Yuck. I know some people believe that everything should always be
initialized
where declared, but do you really think it improves the code to remove the
j = 0 initializer in the for loop?

Where exactly did I write that I think skipping initialization in the for
loop improves the code?
 
L

lovecreatesbeauty

Bill Cunningham said:
... I'm getting a huge number when it should be zero.
int main(void)
{
int i[4], j, k;
k = 0;
for (j = 0; k < 4; ++j)
k = k + i[j];
printf("%d\n", k);
}
I know in this case a simple alternative would be
int i[4]={0,0,0,0};

*i type of non-character, i'm not sure if this is portable/right:
memset(i, 0, sizeof i);
And that's fine but what if it were int i[128]; ?

int i[128] = { 0 };

If there is an initialiser, then aggregate elements that are
not explicitly initialised will be zero initialised by default.

the declaration is inside function body, and doesn't have static
duration. i think the values of elements that aren't initialized
aren't zero by default. (6.7.8p21)
 
N

Nick Keighley

   int i[4] = { 0 }, j = 0, k = 0;
    for (; j < 4; ++j)
Yuck.  I know some people believe that everything should always be
initialized
where declared, but do you really think it improves the code to remove the
j = 0 initializer in the for loop?

Where exactly did I write that I think skipping initialization in the for
loop improves the code?

Bill's code initialised j in the for loop. Your's doesn't so
presumably
you think your code is better.

for this reason
 
S

Seebs

the declaration is inside function body, and doesn't have static
duration. i think the values of elements that aren't initialized
aren't zero by default. (6.7.8p21)

Nope. The values of *variables* which aren't initialized aren't zero
by default. If something is even partially initialized, though, it is
treated as though it were fully initialized with anything not initialized
explicitly being initialized to zero.

-s
 
C

Chris M. Thomasson

int i[4] = { 0 }, j = 0, k = 0;
for (; j < 4; ++j)
Yuck. I know some people believe that everything should always be
initialized
where declared, but do you really think it improves the code to remove
the
j = 0 initializer in the for loop?

Where exactly did I write that I think skipping initialization in the
for
loop improves the code?
Bill's code initialised j in the for loop. Your's doesn't so
presumably
you think your code is better.

The only reason why I think the code I posted is better is because it fixed
the bugs in the original.

[...]
 
B

Ben Bacarisse

Richard Heathfield said:
int i[4] = { 0 }, j = 0, k = 0;
for (; j < 4; ++j)

Yuck. I know some people believe that everything should always be
initialized where declared,

I am one such person (although when adjusting other people's code in a
Usenet posting I may leave their declarations alone on the principle
of minimum change).
but do you really think it improves the code to remove the j = 0
initializer in the for loop?

No. We have some choices:

(a) int i = 0; /* foo */ for(; i < n; i++)
(b) int i; /* foo */ for(; i < n; i++) /* BUG */
(c) int i; /* foo */ for(i = 0; i < n; i++)
(d) int i = 0; /* foo */ for(i = 0; i < n; i++)

Given that this is comp.lang.c, I think consideration should be given
to:

(e) /* foo */ for (int i = 0; i < n; i++)

For some people (and I think Bill is one of them) it solves the problem.

<snip>
 
K

Keith Thompson

Richard Heathfield said:
In
<0.8430e8ce8df620245fed.20090914135118BST.871vm9elkp.fsf@bsb.me.uk>,
Ben Bacarisse wrote:



Fair point. I must admit I didn't realise BC was using a conforming
C99 implementation.

He's using gcc, which as we know is not a fully conforming C99
implementation, but it does support declarations in for loop headers
if you give it the right command-line arguments.
 
K

Keith Thompson

Bill Cunningham said:
I'm not. Especially when I stick a macro of __STRICT_ANSI__ in my code.

Which, as I've said, you shouldn't do. Use the "-ansi" command-line
option instead.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,058
Latest member
QQXCharlot

Latest Threads

Top