From: NickC on
I'm unsure about the correct way to write code that doesn't produce gcc's
warnings of "makes integer from pointer without cast."

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
From: Scott Lurndal on
NickC <reply-to(a)works.fine.invalid> writes:
>I'm unsure about the correct way to write code that doesn't produce gcc's
>warnings of "makes integer from pointer without cast."
>
>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');

_R_tfm

$ man popen

change to "output = popen("/bin/ls", "r");

The second arg is a const char *, not a char.

scott

From: Jens Thoms Toerring on
NickC <reply-to(a)works.fine.invalid> wrote:
> I'm unsure about the correct way to write code that doesn't produce gcc's
> warnings of "makes integer from pointer without cast."

> 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 ___ jt(a)toerring.de
\__________________________ http://toerring.de
From: Beej Jorgensen on
NickC <jemmyducks(a)internode.on.net> wrote:
>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.

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

From: NickC on
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
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