Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Odd printf() Behavior

71 views
Skip to first unread message

Brian Dude

unread,
May 7, 2013, 7:02:34 PM5/7/13
to
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

Vincenzo Mercuri

unread,
May 7, 2013, 9:48:24 PM5/7/13
to
On 08/05/2013 01:02, Brian Dude wrote:
> 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*/

'bmpsource' points to anywhere, I guess you skipped a lot of code.

[..]
>
> readBMheader(&Q,bmpsource);
> scan=(int)Q.height;
[..]

was the call to 'readBMheader()' successful? (my guess is that it's not
a void function). And.. you must have a very good reason to cast a value
to 'int'. Why didn't you choose a proper type for the 'scan' variable?

[..]
> 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?

if you mean that two subsequent calls to printf, e.g.:

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

display two different values for 'scan', the only thing that comes to
my mind is 'undefined behaviour', but I'm not sure where in the code
it was raised.

--
Vincenzo Mercuri

BartC

unread,
May 7, 2013, 7:57:21 PM5/7/13
to
"Brian Dude" <aa...@hotSPAM.com> wrote in message
news:fKfit.18304$MS1....@newsfe05.iad...

> 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.)

--
Bartc


Brian Dude

unread,
May 7, 2013, 8:17:08 PM5/7/13
to
On 5/7/2013 7:57 PM, BartC wrote:
> "Brian Dude" <aa...@hotSPAM.com> wrote in message
> news:fKfit.18304$MS1....@newsfe05.iad...
>
>> 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>.

BartC

unread,
May 7, 2013, 8:34:18 PM5/7/13
to
"Brian Dude" <aa...@hotSPAM.com> wrote in message
news:8Qgit.18313$MS1....@newsfe05.iad...
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!)

--
Bartc

Keith Thompson

unread,
May 7, 2013, 9:48:18 PM5/7/13
to
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.

--
Keith Thompson (The_Other_Keith) ks...@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"

James Kuyper

unread,
May 7, 2013, 10:39:57 PM5/7/13
to
On 05/07/2013 07:02 PM, Brian Dude wrote:
> 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.
--
James Kuyper

Vincenzo Mercuri

unread,
May 7, 2013, 11:40:28 PM5/7/13
to
On 08/05/2013 01:02, Brian Dude wrote:
[..]
>
> readBMheader(&Q,bmpsource);
[..]

The few references to functions with a similar name, that I found
searching on google, show this signature:

void ReadBMHeader(FILE *SHGFile, SHGBITMAPHEADER *SHGBM);

While the function you are calling has the first 'r' and the 'h' in its
name both in lowercase (so it cannot be the same function), it may be
highly possible that you actually swapped the argument it takes.
Should you call it as `readBMheader(bmpsource, &Q)' instead? Who knows.

--
Vincenzo Mercuri

Brian Dude

unread,
May 8, 2013, 8:49:09 PM5/8/13
to
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.

Keith Thompson

unread,
May 8, 2013, 11:58:02 PM5/8/13
to
Brian Dude <aa...@hotSPAM.com> writes:
> On 5/7/2013 8:34 PM, BartC wrote:
>> "Brian Dude" <aa...@hotSPAM.com> wrote in message
>> news:8Qgit.18313$MS1....@newsfe05.iad...
>>> On 5/7/2013 7:57 PM, BartC wrote:
>> 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!)

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.)

Brian Dude

unread,
May 9, 2013, 8:25:32 PM5/9/13
to
On 5/8/2013 11:58 PM, Keith Thompson wrote:
>
> 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 :/

Ken Brody

unread,
May 10, 2013, 10:17:33 AM5/10/13
to
On 5/7/2013 8:17 PM, Brian Dude wrote:
> On 5/7/2013 7:57 PM, BartC wrote:
>> "Brian Dude" <aa...@hotSPAM.com> wrote in message
>> news:fKfit.18304$MS1....@newsfe05.iad...
>>
>>> 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?

Keith Thompson

unread,
May 10, 2013, 2:41:54 PM5/10/13
to
This was addressed a couple of days ago, in Message-ID:
<JoCit.12$Jl...@newsfe12.iad>. slwb was actually defined as a long.
(Yes, the OP has been advised to post real code.)
0 new messages