how can i generate warnings for implicit casts that lose bits?

  • Thread starter robert bristow-johnson
  • Start date
K

Keith Thompson

How big is an octet on ternary machines?

An "octet" is by definition 8 bits. If you don't have bits, you can't
have octets. Of course a ternary machine can emulate bits; the answer
to your question then depends on how the emulation is done.

If you use ternary machines, it might be reasonable to refer to a
collection of 8 trits as an "octet". That would conflict with normal
usage, but then so do ternary machines.
 
K

Keith Thompson

Perhaps it does, but on any realistic platform, why would this matter
if we're measuring the size of a short and a long?

Because they're passed to a varargs function (printf), which will try
to access them as ints, so if they're in fact bigger than ints -
regardless of their value - things will go horribly wrong.[/QUOTE]

Correction: things *might* go horribly wrong. Worse, they might go
horribly right. (I say "horribly" because it could result in a
failure to detect the error until the code is ported to another
platform and fails at the most embarrassing posible moment.)
 
K

Keith Thompson

Randy Yates said:
That brings up an interesting question: Doesn't this behavior depend
on the machine's endianness?

For example, consider the statement

printf("sizeof(int) = %d", sizeof(int));

and the case in which int is 16 bits and sizeof() returns 32 bits.

Is it true that a little-endian machine will print this correctly,
while a big-endian machine will not?

Maybe.

As far as standard C is concerned, it's undefined behavior. That
means that the standard says absolutely nothing about what will
happen. It might blow up, it might print correct or incorrect
results, and it might make demons fly out of your nose (not likely,
but if it does you can't complain that it violates the standard).

It's conceivable that 32-bit and 16-bit integers are passed as
arguments in different registers; attempting to read one when you were
promised the other might give you garbage, regardless of endianness.

The solution is quite simple: don't do that.

(I see that this discussion is cross-posted to comp.dsp and
comp.lang.c. That's probably not a good idea.)
 
R

Richard Heathfield

robert bristow-johnson said:
isn't it clear that when i run these lines of code:

a_ulong = 1234567;

a_short_array[26] = a_ulong;

printf("%d, %hx, %x, %lx \n", sizeof(a_short_array),
a_short_array[26], a_short_array[26], a_ulong );

and get this for output:

256, d687, ffffd687, 12d687

that the bits in the hex digits "12" went bye-bye in the assignment
statement?

Yes. the C Standard does not require implementations to produce a
diagnostic message in this circumstance. A conversion is supplied. Of
necessity, if the lvalue is less wide than the rvalue, any information
stored in those extra bits will be lost. Nevertheless, the conversion
is a useful one in situations where no information is lost, and to take
advantage of it does not constitute a syntax error or constraint
violation, so no diagnostic message is required.
i just wanna know what flag to set (if any) that makes the
compiler tell me i might want to check the statement that could
potentially throw away those bits.

Check in a newsgroup that deals with your implementation.
 
E

Erik de Castro Lopo

robert said:
// $ gcc -Wconversion -o hello hello.c

When using gcc, I usually use -Wall -Wextra -Werror which turns
on all warnings and makes all warnings into errors.

Not sure if this will help in your case.

Erik
--
 
K

Keith Thompson

glen herrmannsfeldt said:
C sort of expects a binary representation. Unsigned addition is
module some power of two, and bitwise operators would be very slow
otherwise.

C99 explicitly requires a binary representation. (Emulating binary on
a ternary machine would be valid.)
 
R

Richard Tobin

Because they're passed to a varargs function (printf), which will try
to access them as ints, so if they're in fact bigger than ints -
regardless of their value - things will go horribly wrong.
[/QUOTE]
Correction: things *might* go horribly wrong. Worse, they might go
horribly right.

Going horribly right is just one of the ways it might go horribly wrong.

-- Richard
 
R

Randy Yates

Richard Heathfield said:
Richard Tobin said:


The requirement is to be able to represent at least 256 discrete values.
This can be accomplished in six trits, the relevant trit pattern being
100110.

Wouldn't a "ternary digit" be a "tit"??? "How many tits are in that byte?"...
--
% Randy Yates % "And all that I can do
%% Fuquay-Varina, NC % is say I'm sorry,
%%% 919-577-9882 % that's the way it goes..."
%%%% <[email protected]> % Getting To The Point', *Balance of Power*, ELO
http://home.earthlink.net/~yatescr
 
K

Keith Thompson

robert bristow-johnson said:
i just wanna know what flag to set (if any) that makes the
compiler tell me i might want to check the statement that could
potentially throw away those bits. i would think, from the
description that -Wconversion or -Wall should do it, but it doesn't
and i was wondering if the hardcore C or gcc geeks might know the
magic invocation to generate such a warning.
[...]

Try gnu.gcc.help.
 
J

Jerry Avins

Keith said:
No, a "byte" is by definition the size of a char. The term "byte" may
have other meanings outside the context of C, but sizeof(char) is 1 by
definition.

Isn't a byte in C the larger of character, octet, or smallest
addressable storage element?

Jerry
 
R

Randy Yates

Erik de Castro Lopo said:
When using gcc, I usually use -Wall -Wextra -Werror which turns
on all warnings and makes all warnings into errors.

Not sure if this will help in your case.

It doesn't on my machine.

[yates@localhost tmp]$ gcc -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ./configure
Thread model: posix
gcc version 4.1.2
--
% Randy Yates % "And all that I can do
%% Fuquay-Varina, NC % is say I'm sorry,
%%% 919-577-9882 % that's the way it goes..."
%%%% <[email protected]> % Getting To The Point', *Balance of Power*, ELO
http://home.earthlink.net/~yatescr
 
G

glen herrmannsfeldt

Vladimir Vassilevsky wrote:

(even more snip)
This also makes the assumption that sizeof() returns size in bytes,
whereas sizeof returns the size in chars. Char may be bigger then one byte.

I would say it is the reader of the output that makes that
assumption, not the program. If you write:

printf("sizeof(short) = %d, sizeof(unsigned long) = %d\n",
(int)sizeof(short), (int)sizeof(unsigned long));

then it is more obvious that it is returning the result
of sizeof.

-- glen
 
R

Richard Heathfield

Jerry Avins said:
Keith Thompson wrote:


Isn't a byte in C the larger of character, octet, or smallest
addressable storage element?

Well, that isn't how it's defined! But yes, your rule looks correct to
me. I think it's easier to think of it as 8+ bits wide.
 
R

robert bristow-johnson

robert bristow-johnson said:
isn't it clear that when i run these lines of code:
a_ulong = 1234567;
a_short_array[26] = a_ulong;
printf("%d, %hx, %x, %lx \n", sizeof(a_short_array),
a_short_array[26], a_short_array[26], a_ulong );
and get this for output:
256, d687, ffffd687, 12d687
that the bits in the hex digits "12" went bye-bye in the assignment
statement?

Yes. the C Standard does not require implementations to produce a
diagnostic message in this circumstance. A conversion is supplied. Of
necessity, if the lvalue is less wide than the rvalue, any information
stored in those extra bits will be lost. Nevertheless, the conversion
is a useful one in situations where no information is lost, and to take
advantage of it does not constitute a syntax error or constraint
violation, so no diagnostic message is required.

it just seems to me that this conversion qualifies as one that changes
value. then, according to the gcc doc, it should generate a -
Wconversion warning. it's close to an assignment of one type to
another but less severe. for example, if sizeof(unsigned
short)<sizeof(long) we know that no value is changed in this
assignment:

unsigned short a_ushort;
long a_long;
a_ushort = 4321;
a_long = a_ushort;

so no warning should be generated, no matter what bits are in
a_ushort, there is no change of value. whereas (assuming
sizeof(short)<sizeof(unsigned long)) this:

short a_short;
unsigned long a_ulong;
a_short = -4321;
a_ulong = a_short;

should generate a warning because there are values in the range of the
type (short) that are not in the type (unsigned long). so even if the
number of bits in the word are increasing in the assignment, this
should generate a -Wcondition warning (maybe it does, but it should
also do it for the original example i brought).

so i can see this warning as being functionally different from one of
type checking or even if there is a bit reduction. i just wish it
worked right.
Check in a newsgroup that deals with your implementation.

yeah, i should look for a gnu or gcc newgroup. just dunno where.

r b-j
 
R

robert bristow-johnson

[...]> i just wanna know what flag to set (if any) that makes the
compiler tell me i might want to check the statement that could
potentially throw away those bits. i would think, from the
description that -Wconversion or -Wall should do it, but it doesn't
and i was wondering if the hardcore C or gcc geeks might know the
magic invocation to generate such a warning.

[...]

Try gnu.gcc.help.

thanks. didn't even know about the gnu hierarchy.

r b-j
 
J

Jerry Avins

Richard said:
Jerry Avins said:


Well, that isn't how it's defined! But yes, your rule looks correct to
me. I think it's easier to think of it as 8+ bits wide.

Do you have a better "rule" than mine to tell just how many that '+'
implies?

Jerry
 
G

glen herrmannsfeldt

Randy Yates wrote:

(snip)

As someone else mentioned, %zu has been added to solve the problem.
That brings up an interesting question: Doesn't this behavior depend
on the machine's endianness?
For example, consider the statement
printf("sizeof(int) = %d", sizeof(int));
and the case in which int is 16 bits and sizeof() returns 32 bits.
Is it true that a little-endian machine will print this correctly,
while a big-endian machine will not?

It is reasonably likely that it will, though it is still wrong.
Also, that will only work if you are just printing one of them.

I consider this a disadvantage of little-endian, as it tends to
hide bugs due to type mismatch until it is too late.
Consider also the mistake of printing a 16 bit value with a
format item expecting 32 bits. (or any function expecting
a 32 bit value.) It might work.

-- glen
 
G

glen herrmannsfeldt

robert bristow-johnson wrote:

(snip)
that the bits in the hex digits "12" went bye-bye in the assignment
statement? i just wanna know what flag to set (if any) that makes the
compiler tell me i might want to check the statement that could
potentially throw away those bits. i would think, from the
description that -Wconversion or -Wall should do it, but it doesn't
and i was wondering if the hardcore C or gcc geeks might know the
magic invocation to generate such a warning.

As far as I know, this is part of C.

Note that Java requires a cast for all narrowing conversions.
Maybe you should switch to Java instead.

-- glen
 

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
474,262
Messages
2,571,050
Members
48,769
Latest member
Clifft

Latest Threads

Top