avoiding warnings for "legitimate" casts

B

Bill Waddington

Long time lurker, 1st time poster. I hope this is sufficiently
c related. If not, send me to my room.

I'm porting a driver to a 64-bit platform. I get handed a struct:

typedef struct {
...
size_t dmac_size
} ddi_dma_cookie_t;

On a 64-bit build size_t is 64 bits wide, but all actual values will
fit in a 32 bit variable. Eventually I need to write dmac_size into
a 32-bit device register:

uint32_t dma_count = dma_cookie.dmac_size;

ddi_put32(..., dma_count);

dmac_size is 64 bits wide, ddi_put32 insists on a 32 bit value, so
lint and or the compiler complain about assigning a 64 to a 32. If
I use a cast they complain about casting 64 to 32. The code runs
fine, but I would like a warning-free compile for those cases where
a customer does the compiling.

Is there a "c" way to quiet this kind of warning via casts or passing
through some intermediate variable? Maybe this tool set is too picky.
Tried the FAQ, hope I didn't miss it.

Thanks,
Bill
 
C

Chris Torek

[my summary: program receives a 64-bit value as a size_t, then
converts it to 32 bit, but the compiler sequence, which apparently
includes running an external "picky" checker, warns for either
ordinary assignment or a cast.]
Is there a "c" way to quiet this kind of warning via casts or passing
through some intermediate variable? Maybe this tool set is too picky.

No diagnostic is required for either operation, but your
compiler apparently produces one for both. Unless it has some
way to eliminate that particular warning for that particular
line of code (or all code), you are stuck.

If that particular compiler's warning is especially clever, it
is just barely possible that writing, e.g.,:

void f(uint64_t input_val) {
uint32_t shortened_version;

if (input_val > 0xffffffff)
panic("impossibly large input value");
shortened_version = input_val;
...
}

might not warn. It is slightly more likely that:

if (input_val > 0xffffffff)
panic("impossibly large input value");
shortened_version = input_val & 0xffffffff;

will not warn. But chances are that the warning will occur no
matter what you do, if both casts and ordinary assignments already
warn.

(Note that using uint32_t, not plain int32_t, is potentially
important here, for portable code. Of course, your code is inherently
non-portable -- inasmuch as the device you are driving is also
non-portable anyway; I would venture to bet that it does not work
on the Univac 1100 series or various Crays, which are capable of
supporting ANSI/ISO C -- so in that sense it does not matter anyway.)
 
B

Bill Waddington

[my summary: program receives a 64-bit value as a size_t, then
converts it to 32 bit, but the compiler sequence, which apparently
includes running an external "picky" checker, warns for either
ordinary assignment or a cast.]
Indeed.
Is there a "c" way to quiet this kind of warning via casts or passing
through some intermediate variable? Maybe this tool set is too picky.

No diagnostic is required for either operation, but your
compiler apparently produces one for both. Unless it has some
way to eliminate that particular warning for that particular
line of code (or all code), you are stuck.

Figured I was stuck, but my skills are sufficiently feeble that I
thought it best to ask. I can turn off the cast check, but only
globally. Probably not a good idea.
If that particular compiler's warning is especially clever, it
is just barely possible that writing, e.g.,:

void f(uint64_t input_val) {
uint32_t shortened_version;

if (input_val > 0xffffffff)
panic("impossibly large input value");
shortened_version = input_val;
...
}

might not warn. It is slightly more likely that:

if (input_val > 0xffffffff)
panic("impossibly large input value");
shortened_version = input_val & 0xffffffff;

will not warn. But chances are that the warning will occur no
matter what you do, if both casts and ordinary assignments already
warn.

I'll give this a try, but I'm not optimistic. My best bet is to just
document the warnings in my README I guess.
(Note that using uint32_t, not plain int32_t, is potentially
important here, for portable code. Of course, your code is inherently
non-portable -- inasmuch as the device you are driving is also
non-portable anyway; I would venture to bet that it does not work
on the Univac 1100 series or various Crays, which are capable of
supporting ANSI/ISO C -- so in that sense it does not matter anyway.)

Anything with a PCI slot. In this case an Opteron running Solaris 10,
Studio 10 cc and lint.

Portability doesn't matter this time, but I would like to improve
my game re c coding when possible...

Thanks for your time,
Bill
 
S

Steffen Fiksdal

[my summary: program receives a 64-bit value as a size_t, then
converts it to 32 bit, but the compiler sequence, which apparently
includes running an external "picky" checker, warns for either
ordinary assignment or a cast.]
Indeed.
Is there a "c" way to quiet this kind of warning via casts or passing
through some intermediate variable? Maybe this tool set is too picky.

No diagnostic is required for either operation, but your
compiler apparently produces one for both. Unless it has some
way to eliminate that particular warning for that particular
line of code (or all code), you are stuck.

Figured I was stuck, but my skills are sufficiently feeble that I
thought it best to ask. I can turn off the cast check, but only
globally. Probably not a good idea.

I believe the function you are calling sucks bigtime....

I'll give this a try, but I'm not optimistic. My best bet is to just
document the warnings in my README I guess.

Yes, document that the function you are calling sucks bigtime...
 
T

those who know me have no need of my name

in comp.lang.c i read:

[member dmac_size has type size_t, which is 64 bits on the op's platform]
uint32_t dma_count = dma_cookie.dmac_size;
lint and or the compiler complain about assigning a 64 to a 32.

lints can often be told that the assignment is intentional, and it may be
that your compiler uses the same mechanism so that a single annotation
works for both. this is if you are lucky.

the horrible way to silence the warning if nothing else works may be a
cast:

uint32_t dma_count = (uint32_t)dma_cookie.dmac_size;

compilers are allowed to output most anything they like any time they like,
so if nothing works then you'll just have to accept it -- or switch to a
more sensible compiler. lint is there to try to warn about things which
may be risky, so they are supposed to produce warnings if there's any
chance your code might have behavior that can be surprising.
 
J

Jonathan Adams

Bill Waddington said:
uint32_t dma_count = dma_cookie.dmac_size;

ddi_put32(..., dma_count);

dmac_size is 64 bits wide, ddi_put32 insists on a 32 bit value, so
lint and or the compiler complain about assigning a 64 to a 32. If
I use a cast they complain about casting 64 to 32. The code runs
fine, but I would like a warning-free compile for those cases where
a customer does the compiling.

If you can get it so that only lint complains, then you can just put
/* LINTED */
on the line beforehand, to shut lint up.

Cheers,
- jonathan
 
B

Bill Waddington

If you can get it so that only lint complains, then you can just put
/* LINTED */
on the line beforehand, to shut lint up.

Nuts. I missed that "generic" directive when I dug throught the docs.
I will probably use NOTE(LINTED()) w/this set of tools. Maybe use
a msg arg to print "ignore this..."

Thanks,
Bill
 

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,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top