Odd printf() Behavior

B

Brian Dude

Hello, I'm working on some graphics routines and just started trying to
read in some bitmap files. For troubleshooting, I'm printing out various
values to make sure they're all okay.

I have two globals and a local whose values I wanted to verify. I made a
bitmap header structure for obtaining info.

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
struct W3_BMP_header Q;
long int X;
FILE *bmpsource;
/*other variables*/

readBMheader(&Q,bmpsource);
scan=(int)Q.height;
X= Q.width%2==0 ? Q.width/2 : Q.width/2+1;
slwb=X+(4-X%4)%4;
chunx=(int)(Q.width/8+(Q.width%8>0));
printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in
this particular printf() call. Both 'chunx' and 'slwb' show up
correctly. I made a separate printf() call displaying only the 'scan'
variable (both before and after the other printf), and it shows up fine.
What's going on?

TIA,
Brian Dude
 
B

BartC

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in this
particular printf() call. Both 'chunx' and 'slwb' show up correctly.

Is the above the code *exactly* as you have it?

I can make scan come up 0 when slwb is made 'long long int' instead of 'int'
(so that it occupies 64-bits in the parameter list, and %d expects only
32-bits; the extra 32-bits is read by the final "%d", and happen to be
zero). There might be other ways this can happen.

What happens if you mix up the order of these three variables? What if you
add one or two extra 'scan' arguments to the printf, together with two more
%d formats; are those zero too? (Perhaps change "%d" for scan, to "<%d>", to
check the final characters are not suppressed, hidden, or overwritten for
any reason, and the zero doesn't belong to anything else.)
 
B

Brian Dude

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in this
particular printf() call. Both 'chunx' and 'slwb' show up correctly.

Is the above the code *exactly* as you have it?

It's almost exact, but not 100%.
I can make scan come up 0 when slwb is made 'long long int' instead of
'int'
(so that it occupies 64-bits in the parameter list, and %d expects only
32-bits; the extra 32-bits is read by the final "%d", and happen to be
zero). There might be other ways this can happen.

What happens if you mix up the order of these three variables? What if you
add one or two extra 'scan' arguments to the printf, together with two more
%d formats; are those zero too? (Perhaps change "%d" for scan, to
"<%d>", to check the final characters are not suppressed, hidden, or
overwritten for any reason, and the zero doesn't belong to anything else.)

I tried rearranging the arguments:

printf("\nchunx = %d\nscan = %d\nslwb = %d\n",chunx,scan,slwb);

and all three printed correctly. I then put them back into the original
order and put the angle brackets around 'scan'. It printed as <0>.
 
B

BartC

Brian Dude said:
On 5/7/2013 7:57 PM, BartC wrote:

I tried rearranging the arguments:

printf("\nchunx = %d\nscan = %d\nslwb = %d\n",chunx,scan,slwb);


OK, try these (assuming that removing the labels doesn't hide the problem):

printf("%d %d %d %d\n", chunx, slwb, scan, 12345);
printf("%d %d %d %d\n", chunx, scan, slwb, 12345);

What's shown after the 0 of scan in the first printf?

Also perhaps:

printf("%d %d %d\n", sizeof chunx, sizeof slwb, sizeof scan);

(They should all be the same!)
 
K

Keith Thompson

Brian Dude said:
Hello, I'm working on some graphics routines and just started trying to
read in some bitmap files. For troubleshooting, I'm printing out various
values to make sure they're all okay.

I have two globals and a local whose values I wanted to verify. I made a
bitmap header structure for obtaining info.

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
struct W3_BMP_header Q;
long int X;
FILE *bmpsource;
/*other variables*/

readBMheader(&Q,bmpsource);
scan=(int)Q.height;
X= Q.width%2==0 ? Q.width/2 : Q.width/2+1;
slwb=X+(4-X%4)%4;
chunx=(int)(Q.width/8+(Q.width%8>0));
printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in
this particular printf() call. Both 'chunx' and 'slwb' show up
correctly. I made a separate printf() call displaying only the 'scan'
variable (both before and after the other printf), and it shows up fine.
What's going on?

Try adding *exactly* the following lines immediately after your existing
printf call:

printf("chunx = %d\n", chunx);
printf("slwb = %d\n", slwb);
printf("scan = %d\n", scan);

Do these printf calls show the same values as your existing printf call,
and are those values correct?

Incidentally, the casts are unnecessary. If Q.height isn't of type int,
it will be implicitly converted to int by the assignment. (And if
Q.height isn't of type int, I wonder why scan isn't of the same type.)
Likewise for chunx.
 
J

James Kuyper

Hello, I'm working on some graphics routines and just started trying to
read in some bitmap files. For troubleshooting, I'm printing out various
values to make sure they're all okay.

I have two globals and a local whose values I wanted to verify. I made a
bitmap header structure for obtaining info.

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
struct W3_BMP_header Q;
long int X;
FILE *bmpsource;

bmpsource is uninitialized here.
/*other variables*/

readBMheader(&Q,bmpsource);

You use bmpsource here, despite the fact that it hasn't been
initialized. I hope that in your actual code, bmpsource is filled in by
a call to fopen()? Another indication that this program is incomplete is
your use of struct W3_BMP_header, FILE, readBMPheader(), and printf().
Each of those is probably declared in a header file, and your code, as
written, doesn't #include any headers.

Please keep in mind that if you knew what was wrong with your program,
you wouldn't be coming here for help. Since you don't know what's wrong
with it, there's a very good chance that something you think is
irrelevant, isn't. Therefore, don't cut out anything just because you
think it's irrelevant. Show us a program as simple as possible, while
still demonstrating the problem. However, show us the complete program,
not just the part you think is relevant. Do not re-type the program -
cut and paste it directly from the source - otherwise we may end up
wasting time investigating the typos you introduced while re-typing the
code.
scan=(int)Q.height;

Q.height was uninitialized at the start of your program. The only code
you've shown us that had any chance of setting it to a defined value
before this line is executed was the call to readBMPheader(). Therefore,
if some thing's wrong, it's probably because readBMPheader() is not
doing what you think it should be doing. This, in turn, is probably
because you were wrong about what you thought it should be doing (the
problem could be in readBMPheader(), but in general it's more likely to
be your code). That means that this isn't a C problem, it's a problem
with whatever package readBMPheader() is part of. Therefore, you'll
probably get better help with your problem by taking it to a forum
devoted to that package. comp.lang.c isn't that forum.
 
B

Brian Dude

OK, try these (assuming that removing the labels doesn't hide the problem):

printf("%d %d %d %d\n", chunx, slwb, scan, 12345);
printf("%d %d %d %d\n", chunx, scan, slwb, 12345);

What's shown after the 0 of scan in the first printf?

Also perhaps:

printf("%d %d %d\n", sizeof chunx, sizeof slwb, sizeof scan);

(They should all be the same!)

Ahh, thank you for the sizeof idea. I accidentally had 'slwb' as a long
(so the results *were* different). I'm been working on this function for
too long, I should have stepped away for a bit and come back later.
 
K

Keith Thompson

Don't use "%d" to print the result of sizeof. The sizeof operator
yields a result of type size_t. If int and size_t happen to be the same
size, it's likely to "work", but it's better to use explicit casts:

printf("%d %d %d\n", (int)sizeof chunx, (int)sizeof slwb, (int)sizeof scan);

or to use the "%zu" format, which is specifically intended for size_t values:

printf("%zu %zu %zu\n", sizeof chunx, sizeof slwb, sizeof scan);

(The only real reason *not* to use the latter is that some old
implementations may not support "%zu", which was added by C99.)
Ahh, thank you for the sizeof idea. I accidentally had 'slwb' as a long
(so the results *were* different). I'm been working on this function for
too long, I should have stepped away for a bit and come back later.

This is why you *really* need to post the exact code that you're
compiling. Don't summarize it, don't re-type it, copy-and-paste it.
Feel free to trim it down to something small enough to post, but
verify that the trimmed version exhibits the problem before you
post it here. (The code you posted clearly defined slwb as an int,
so it was impossible for anyone to help you.)
 
B

Brian Dude

This is why you *really* need to post the exact code that you're
compiling. Don't summarize it, don't re-type it, copy-and-paste it.
Feel free to trim it down to something small enough to post, but
verify that the trimmed version exhibits the problem before you
post it here. (The code you posted clearly defined slwb as an int,
so it was impossible for anyone to help you.)

Yes. Quite right :/
 
K

Ken Brody

int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/
printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in this
particular printf() call. Both 'chunx' and 'slwb' show up correctly.

Is the above the code *exactly* as you have it?

It's almost exact, but not 100%.
[...]

Why not? If you say that a printf() line prints the wrong value for a
variable, but a different printf() prints the correct value, what make you
think that giving us the "almost exact" printf() is of any use?

Does the printf() that you gave above, if used "100% exact" as you posted in
your question, work or not work?

What is the "100% exact" printf() statement that does fail?

Are the definitions of chunx, slwb, and scan "100% exact"? If not, then
how, exactly, are they defined?
 
K

Keith Thompson

Ken Brody said:
int chunx;
int scan;

int main(int argc,char *argv[])
{
int slwb; /*Scan Line Width in Bytes*/

printf("\nchunx = %d\nslwb = %d\nscan = %d\n",chunx,slwb,scan);

For some reason, the value for 'scan' keeps showing up as 0, only in this
particular printf() call. Both 'chunx' and 'slwb' show up correctly.

Is the above the code *exactly* as you have it?

It's almost exact, but not 100%.
[...]

Why not? If you say that a printf() line prints the wrong value for a
variable, but a different printf() prints the correct value, what make you
think that giving us the "almost exact" printf() is of any use?

Does the printf() that you gave above, if used "100% exact" as you posted in
your question, work or not work?

What is the "100% exact" printf() statement that does fail?

Are the definitions of chunx, slwb, and scan "100% exact"? If not, then
how, exactly, are they defined?

This was addressed a couple of days ago, in Message-ID:
<[email protected]>. slwb was actually defined as a long.
(Yes, the OP has been advised to post real code.)
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top