Four or Two Bytes?

H

Hahnemann

Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?

file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fclose(file); // File written as 4 bytes... hmm
}

- Hahnemann
 
C

Chris McDonald

Hahnemann said:
Does anybody know the answer to the following? An unsigned short is 2
bytes long. Why is the following file created as 4 bytes instead of
2?
file = fopen("data.bin", "wb");
if (file != NULL)
{
unsigned short s = 65535;
printf("Size of unsigned short: %d bytes\n", sizeof(unsigned
short)); // 2 bytes - OK
fwrite(&s, sizeof(unsigned short), sizeof(s), file);
fclose(file); // File written as 4 bytes... hmm
}


Because you're asking it to?
Check the 3rd parameter of fwrite().
 
H

Hahnemann

Because you're asking it to?
Check the 3rd parameter of fwrite().

But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes. How can I make the file 2 bytes using:

unsigned short x = 65535;

Is this even possible?
 
P

Peter Nilsson

You mean _if_?

Because 2 lots of 2 bytes is 4 bytes.
But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes.  How can I make the file 2 bytes
using:

By only outputting 2 bytes once, instead of twice.
unsigned short x = 65535;

Is this even possible?

Hangliding is a topic best researched _before_ you
through yourself off the cliff. ;)
 
K

Keith Thompson

Hahnemann said:
But notice that:

printf("Size of s: %d bytes\n", sizeof(s)) ;

returns 2 bytes.

Yes, but ...

"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);

And though unsigned short is 2 bytes on your implementation, that's
not guaranteed; it could be different on other implementations.
How can I make the file 2 bytes using:

unsigned short x = 65535;

Is this even possible?

Certainly.

fwrite() writes a specified number of elements. In your case, the
element(s) are of type unsigned short. The second argument is the
size of each element (you're passing ``sizeof(unsigned short)'', which
is ok). The third argument is the number of elements (you're passing
``sizeof(s)''). How many elements do you want to write (hint: 1).
 
M

Martin

"%d" expects an argument of type int; you're giving it an argument of
type size_t. You should cast the value to int (one of the few cases
where a cast is appropriate):

printf("Size of s: %d bytes\n", (int)sizeof s);

Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?
 
J

Joachim Schmitz

Martin said:
Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?
Guess Keith's point is that you should cast it to whatever the format
specified expects.

Bye, Jojo
 
M

Martin

Guess Keith's point is that you should cast it to whatever the format
specified expects.

I'll wait for Keith's response, but I would say that sometimes it may be
better to change the format specified. Casting an unsigned type to signed
type of equal or less width has the potential for data loss.
 
J

Joachim Schmitz

Martin said:
I'll wait for Keith's response, but I would say that sometimes it may
be better to change the format specified. Casting an unsigned type to
signed type of equal or less width has the potential for data loss.
Yes it might have, but how likely is it that a data type is really larger
than INT_MAX?
 
J

Joachim Schmitz

CBFalconer said:
If you simply examine limits.h you will probably find that UINT_MAX
is roughly twice the size of INT_MAX. To me, this indicates your
probability is roughly 2:1. Anything over 0 is bad.
So what? The basic daty types have sizes of 1 to 8 bytes. Sensibel structs
and arrays are most probaly well smaller than 32K, which is the minimun for
INT_MAX, so again: how big is the chance that a real life data type is
larger than that?

Bye, Jojo
 
J

Joachim Schmitz

Joachim said:
So what? The basic daty types have sizes of 1 to 8 bytes. Sensibel
structs and arrays are most probaly well smaller than 32K, which is
the minimun for INT_MAX, so again: how big is the chance that a real
life data type is larger than that?
On top of that: here it is about 2 or 4, which even on the DS9K would easily
fit into INT_MAX.

Bye, Jojo
 
K

Keith Thompson

Martin said:
Generally, isn't it better to use

printf("Size of s: %lu bytes\n", (unsigned long)sizeof s);

as recommended in the answer to FAQ question 7.15?

Yes. In this particular case, the expression ``sizeof s'' is the size
of an object of type unsigned short, so it's practically certain to be
no greater than INT_MAX. But using int rather than unsigned long was
just laziness in my part; IMHO it's better to get into the habit of
using unsigned long whether it's necessary or not, rather than wasting
time figuring out whether int is ok in this or that particular
instance.

In C99, you can use

printf("Size of s: %zu bytes\n", sizeof s);

to print a size_t value directly. I look forward eagerly to the day
when C99 is widely implemented and that code is reasonably portable.
 
K

Keith Thompson

pete said:
Not on the DS9K.
unsigned short can have INT_MAX padding bytes on the DS9K.

Padding *bits*, not padding bytes.

But I think you have to pay for the commercial version of the DS9K C
compiler to get unsigned short with CHAR_BIT*INT_MAX padding bits; the
free version only has sizeof(unsigned short)==INT_MAX.
 
K

Kenneth Brody

Joachim said:
Yes it might have, but how likely is it that a data type is really larger
than INT_MAX?

As I recall, "huge model" on real-mode x86 processors use 32-bit
pointers, yet 16-bit ints. As such, I would expect that size_t
could hold values larger than INT_MAX.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

Keith Thompson

Kenneth Brody said:
As I recall, "huge model" on real-mode x86 processors use 32-bit
pointers, yet 16-bit ints. As such, I would expect that size_t
could hold values larger than INT_MAX.

Which is not particularly relevant in this case. The issue, as
Joachim wrote, is whether "a data type is really larger than INT_MAX".
It's not about whether the data type (unsigned short in this case) is
able to hold values larger than INT_MAX; it's about whether the size
of the data type is larger than INT_MAX bytes.

If I had an integer type bigger than 262136 bits, I don't think I'd
call it "short".
 
C

Chris McDonald

N869
6.2.6.2 Integer types
[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.


One has to feel sorry for the OP at this point!
 
J

Joachim Schmitz

pete said:
N869
6.2.6.2 Integer types

[#1] For unsigned integer types other than unsigned char,
the bits of the object representation shall be divided into
two groups: value bits and padding bits (there need not be
any of the latter). If there are N value bits, each bit
shall represent a different power of 2 between 1 and 2N-1,
so that objects of that type shall be capable of
representing values from 0 to 2N-1 using a pure binary
representation; this shall be known as the value
representation. The values of any padding bits are
unspecified.
N1256
5.2.4.2.1 Sizes of integer types <limits.h>

....

Their implementation-defined values shall be equal or greater in magnitude

(absolute value) to those shown, with the same sign.

....

- maximum value for an object of type int

INT_MAX +32767 // 215 - 1





So even on a DS9K printf's %d has to be able to display numbers up to 32767.



Bye, Jojo
 
K

Keith Thompson

pete said:
I refer to a byte composed entirely of padding bits,
as a "padding byte".

Ok, but the standard doesn't. In fact, the standard specifically uses
the phrase "padding bytes" for padding in structs or unions.

[...]
 
B

Barry Schwarz

fwrite(
pointer to buffer ... ok
size of an element of that buffer ... 2
number of elements to write ... 2
handle for file write should occur to ... ok

So, 2 elements of 2 bytes each should write four bytes.


So, fwrite worked correctly. More or less, since it wrote out 4 bytes from
a 2 byte object. It could just about as easily have crashed when it went
beyond the bounds of the object.

Actually, fwrite invoked undefined behavior and only appeared to work
correctly because the OP was using it on a system where he was allowed
to access memory beyond the end of s. On a well-behaved system (tm),
his program would have been interrupted in an implementation defined
manner.


Remove del for email
 

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

Similar Threads

Adding adressing of IPv6 to program 1
URGENT 1
error 28
Windows LLDP Driver Responds With No Data 0
Problem Reading Bmp's .. 14
Writing "ls" under windows 39
fread/fwrite 2 18
writing into file using structures 5

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,906
Latest member
SkinfixSkintag

Latest Threads

Top