In this case, it is using popen, but I guess my question could be reworked
to read "do I /really/ have to cast to pointer every single time I use a
constant char? Isn't that a lot of extra work, whereas the compiler
should be able to detect, analyse, and handle without warning if it's not
needed?"
With this code:
FILE *output;
output = popen("/bin/ls", 'r');
gcc warns that:
passing argument 2 of 'popen' makes integer from pointer without a cast.
So edited to:
output = popen("/bin/ls", (void *)'r')
gcc now complains that:
passing argument 1 of 'read' makes integer from pointer without a cast.
which I'm guessing means that a lower-level call in popen uses 'read' and
that's why gcc complains. I don't know how to "pass" the cast down
through to 'read'. (Does this mean popen is a macro? Otherwise how does
gcc know about the library internals of the inner workings of popen?).
I'm a little unsure about when I should be concerned about the whole
"integer from pointer" thing with gcc. Ideally I should be aiming for no
warnings. But, does this mean I have to cast to pointer every time I use
a constant char? In which case, is gcc crying wolf a bit too often?
Thanks for any help,
--
NickC
Linux 2.6.27
Slackware 12.2
_R_tfm
$ man popen
change to "output = popen("/bin/ls", "r");
The second arg is a const char *, not a char.
scott
> In this case, it is using popen, but I guess my question could be reworked
> to read "do I /really/ have to cast to pointer every single time I use a
> constant char? Isn't that a lot of extra work, whereas the compiler
> should be able to detect, analyse, and handle without warning if it's not
> needed?"
> With this code:
> FILE *output;
> output = popen("/bin/ls", 'r');
> gcc warns that:
> passing argument 2 of 'popen' makes integer from pointer without a cast.
That's because you don't call popen() with the arguments it expects.
The second argument must be a pointer to a string. If you look at
the man page for popen() you will find that it's declared as
FILE *popen(const char *command, const char *type);
and not with 'const char type' for the second argument. But what
you pass to is a (const) char, which, according to the normal rules
of promotion of arguments, is converted to an int. That's why you
get this warning. The way to go is *not* to cast anything (casting
is rarely needed, and if you do it you should understand very well
why you're doing it, otherwise it's very likely for the wrong rea-
sons and you will end up with a harder to find bug). Simply do
output = popen("/bin/ls", "r");
(i.e. pass it the string it expects instead of a char, note the
double instead of single quotes) and you will be fine.
> I'm a little unsure about when I should be concerned about the whole
> "integer from pointer" thing with gcc.
Yes, you should. It is *always* a sign that you made a bad mistake,
either not using the proper arguments or having missed to include
the header file with the declaration of the function you're using.
> But, does this mean I have to cast to pointer every time I use
> a constant char? In which case, is gcc crying wolf a bit too often?
If the function expects a string and you pass it a char then you
made a mistake and gcc is just trying to help you. In all my 20
years of programming in C I haven't got this warning once without
good reasons but because I made a stupid mistake. I would go as
far as saying that this should be made an error and not just a
warning.
And refrain from casting except in situations were you fully under-
stand why you have to do it. When I see a cast in a program I con-
sider it as a "red flag", telling me that this is something I have
to take a closer look at since something potentially dangerous is
going on. It basically says "I, the programmer, know better than
the compiler". Unfortunately, not all programmers know better than
the compiler and just put in casts to keep the compiler from emit-
ting helpful hints, not understanding what they're doing.
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de
Actually I'm guessing it likely said:
passing argument 2 of ‘popen’ makes pointer from integer without a cast
This means you have a pointer/integer type mismatch in your argument
list, virtually always a sign of a very serious problem.
>output = popen("/bin/ls", (void *)'r')
A pint says your program segfaults when this line executes, warning or
not.
>gcc now complains that:
>passing argument 1 of 'read' makes integer from pointer without a cast.
Are you sure this warning is on the popen() line? On my gcc install,
putting the (void*) in the popen() call causes it to build warning-free.
#include <stdio.h>
int main(void)
{
FILE *output;
output = popen("/bin/ls", (void*)'r');
return 0;
}
$ cc -Wall -o foo foo.c
$ ./foo
Segmentation fault
>I'm a little unsure about when I should be concerned about the whole
>"integer from pointer" thing with gcc.
Here's another vote for "extremely concerned" and "don't just cast it
away". Don't hide the warning; fix the error.
-Beej
> programming in C I haven't got this warning once without good reasons
> but because I made a stupid mistake.
Yep, spot on. I *know* it needed a string yet I was fixated on char,
probably a hangover from the old BASIC days (I very rarely do FILE stuff
in C, probably the last time was 10 years ago).
> And refrain from casting except in situations were you fully under-
> stand why you have to do it. When I see a cast in a program I con- sider
> it as a "red flag", telling me that this is something I have to take a
> closer look at since something potentially dangerous is going on. It
> basically says "I, the programmer, know better than the compiler".
Ok, will do, thanks for this detail. I had in the back of my mind some
advice somewhere in "Joy of C" that talked about casting parameters to
ensure the correct type and avoid these warning msgs, but perhaps that
advice was written before C compilers got as advanced as they are now, esp
gcc.
BTW, the 'read' stuff? Forget it, gcc was warning about the read() call
in the next line, whose line number had changed while I was editing the
file for my original example, and I was confusing it with the popen() call.
Thanks,
--
NickC
Thanks for the reply. You are right, it's from read(), see my other reply
previously. I'm now using fread() with no problems. I'd confused an fd
with a FILE, mistakenly assuming they were the same thing.
--
NickC
There actually are a few situation where you have no choice but
to cast, one prominent one is the connect(2) function, which
expects as it's second argument a 'const struct sockaddr *' but
where this can be a different beast, depending on if this for a
AF_UNIX socket or "real" network socket (the third argument with
the size of what you actually passed allows the function to figure
out what it got - if I got that wrong Beej Jorgensen, who also ans-
wered you question will be able to explain it much better than me
since he's a well-known expert on socket programming). Another
place where a cast is prudent to use a cast is with the is*() func-
tions from <ctype.h> (isdigit(), isascii() etc.) where there is an
ambiguity due to some systems having signed and others unsigned
chars when you have a unqualified "char", and you get around that
by casting the argument to unsigned char. And, finally, there are
some issues with variadic functions, i.e. functions that have an
unspecified number of arguments (the ones with '...' at the end of
the argument list) and instead rely on a "format string" that tells
the function about the types of the arguments covered by '...'. Here
it's also sometimes necessary to cast the types of the arguments to
make sure they fit exactly what's stated in the format string.
So there are some cases where casts of function arguments actually
make sense or even are required. But out of the three examples I
came up with above only the first one would result in the compiler
emitting a warning. So all situations that seem to require a cast to
keep the compiler from warning you should make you wary and inves-
tigate what's going on - admittedly that might be a bit tedious but
it's normally worth the effort.
You got it right--except the word "expert" is probably a little bit
strong. Actually the whole sockets API uses this liberally in a variety
of calls as a form of C inheritance.
-Beej
> You got it right--except the word "expert" is probably a little bit
> strong.
Well, as the author of the very often cited guide on network
programming - for those who haven't bookmarked it yet it's at
- calling you an expert doesn't seem to me to be too far off the
mark, at least it indicates that a lot of people think you know
very well what you're talking about;-)
> On Fri, 11 Dec 2009 23:56:55 +0000, Jens Thoms Toerring wrote:
>
>
> > programming in C I haven't got this warning once without good reasons
> > but because I made a stupid mistake.
>
> Yep, spot on. I *know* it needed a string yet I was fixated on char,
> probably a hangover from the old BASIC days (I very rarely do FILE stuff
I think you mean "holdover". A hangover is what you get from drinking
too much, although that could also cause you to make programming
mistakes.
> in C, probably the last time was 10 years ago).
I was guessing it was a holdover from Perl, which doesn't have a char
type, and uses both "" and '' to delimit strings. It's been more than
25 years since I've programmed in BASIC, but I don't recall it using ''
for strings (IIRC, ' was used to introduce comments).
--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
I would assume it tests the sa_family_t in the struct, which contains
the address family. There's no reason why two incompatible sockaddr
types couldn't have identical size.
[snip]
> And, finally, there are
> some issues with variadic functions, i.e. functions that have an
> unspecified number of arguments (the ones with '...' at the end of
> the argument list) and instead rely on a "format string" that tells
> the function about the types of the arguments covered by '...'. Here
> it's also sometimes necessary to cast the types of the arguments to
> make sure they fit exactly what's stated in the format string.
This is because the compiler can't possibly know what, if any,
conversions to apply. So it uses a set of rules called default argument
promotions. The same rules are used when there is no prototype in scope
for a function that is called.
Another case where this shows up specifically in Unix programming is
with execl*(). NULL may be #defined to 0, so terminating the argument
list with NULL may cause an integer to be passed to the function instead
of a null pointer to char. (char *)0 or (char *)NULL are correct.
[...]
> Another place where a cast is prudent to use a cast is with the
> is*() functions from <ctype.h> (isdigit(), isascii() etc.) where
> there is an ambiguity due to some systems having signed and others
> unsigned chars when you have a unqualified "char", and you get
> around that by casting the argument to unsigned char.
It is at least debatable if such cast has a defined behaviour. The
only pointer-casts allowed by the C-standard are casts to pointers to
compatible types and AFAIK, signed char, char and unsigned char are
not explicitly required to be compatible.
> [...]
In that case you should cast the value of what you pass to one
the functions from <ctype.h> to unsigned char (not a pointer)
since the C standard requires:
The header <ctype.h> declares several functions useful for testing
and mapping characters. In all cases the argument is an int, the
value of which shall be representable as an unsigned char or shall
equal the value of the macro EOF. If the argument has any other
value, the behavior is undefined.
On a system with signed chars, if you pass a negative char to the
functions (i.e. some non-ASCII char) the value, if taken as an int,
could be a number that's neither representable by an unsigned char
nor is EOF. That's, as far I understand it, the rationale for cas-
ting to unsigned char in these cases.
I should read postings more carefully ... thanks for the correction.
>> probably a hangover from the old BASIC days (I very rarely do FILE stuff
>
> I think you mean "holdover". A hangover is what you get from drinking
> too much, although that could also cause you to make programming
> mistakes.
http://www.askoxford.com/concise_oed/hangover?view=uk
hangover
noun
1 a severe headache or other after-effects caused by drinking an
excess of alcohol.
2 a thing that has survived from the past.
http://www.askoxford.com/concise_oed/holdover?view=uk
Not Found
http://www.askoxford.com/concise_oed/hold_1?view=uk
-- PHRASES
[...]
hold over
1 postpone.
2 use (information) to threaten.
--
Geoff Clare <net...@gclare.org.uk>