printf("My pid is %d\n",getpid());
The problem is that getpid() is pid_t, and there's no printf conversion
character for pid_t's. It complains that it is an int format and a pid_t
arg.
To fix it, you have to do: (int) getpid()
I'm curious as to:
1) Who's at fault for this?
2) Is there a general solution to the problem of there not being
printf conversion characters for other than the standard types?
> 2) Is there a general solution to the problem of there not being
> printf conversion characters for other than the standard types?
[-]
Sure, cast it to a standard type ;) I'd prefer an unsigned though, read
unsigned long as a process id is never going to be negative.
Ta',
Juergen
--
\ Real name : Juergen Heinzl \ no flames /
\ EMail Private : jue...@monocerus.demon.co.uk \ send money instead /
The problem is this. The following principles are inconsistent with each
other:
1) The compiler is correctly implemented (bug free) (*)
2) Your code should always compile without any warnings (I.e.,
it should be lint-free)
3) Having non-standard types for ordinary things (I.e., pid_t when
everybody knows it's really an int) is a good thing.
(*) In case this is unclear, my point here is that the compiler is correct
in issuing a warning for this sort of thing.
I note, BTW, that only some versions/implementations of GCC flag this one,
so it may be that assumption #1 is the flawed assumption.
No errors here.
$ cat test.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int
main()
{
printf("My pid is %d\n", getpid());
return 0;
}
$ gcc -Wall -ansi -pedantic test.c
$ ./a.out
My pid is 37606
$ gcc -v
Reading specs from /home/graywane/atl/lib/gcc-lib/i386-unknown-freebsd4.3/3.0/specs
Configured with: /home/graywane/work/gcc/configure --prefix=/home/graywane/atl --disable-shared --disable-nls
gcc version 3.0 20010406 (prerelease)
--
Note: There is no example in my hostname.
Aha! In fact, I just figured out what the problem is. pid_t is, on the
system in question, (typedef'd to) long, thus the compiler flags this as an
error (warning). Comments:
1) FWIW, ints and longs are both 32 bits on this system, so the
whole thing ought to be moot.
2) Its pretty stupid to make pid_t long - I think the most rational
choice would be "unsigned int" (as you allude to above).
3) Pids never get larger than about 30,000 anyway (at least on any
Unix system I've ever seen), so a (signed) short is really enough.
4) The real underlying problem here is that you can't write
portable, lint-free code. In one form or another, this bugaboo
could pop up anywhere. And note that casting the result
(getpid()) to int can't be the right solution - as is the case
with most instances of casting, it is a kludge - and it could
actually be a problem on a system where ints and pid_ts really
were different sizes.
The only really correct solution is to delve into the include files on the
affected system, figure out what a pid_t is, and then change the printf
format specifier accordingly (via appropriate #ifdefs, of course).
But doesn't that just seem like more trouble than it is worth???
> 2) Its pretty stupid to make pid_t long - I think the most rational
> choice would be "unsigned int" (as you allude to above).
[-]
Maybe you're using a system which is available for 64 bit architectures, too ?
It might explain the usage of long to stay consistent. Just an idea, sure.
> 3) Pids never get larger than about 30,000 anyway (at least on any
> Unix system I've ever seen), so a (signed) short is really enough.
[-]
Well, better safe than sorry ;)
> 4) The real underlying problem here is that you can't write
> portable, lint-free code. In one form or another, this bugaboo
> could pop up anywhere. And note that casting the result
> (getpid()) to int can't be the right solution - as is the case
> with most instances of casting, it is a kludge - and it could
> actually be a problem on a system where ints and pid_ts really
> were different sizes.
[-]
Yes. It's why I wrote use unsigned long since then you're probably on
the safe side. Of course some time in the future systems may require
long long's for process ID's, though I'm being hopeful to spend my
penison on some isle in the South Sea by then (it ought to buy me
a drink or two at least .. I hope).
>The only really correct solution is to delve into the include files on the
>affected system, figure out what a pid_t is, and then change the printf
>format specifier accordingly (via appropriate #ifdefs, of course).
>
>But doesn't that just seem like more trouble than it is worth???
[-]
I'd prefer the cast, though not to a signed int for it's legal, less
hassle and I try not to know what's behind a typedef; there're just
to many. Why bother when keeping it it simple and stupid does the job ?
But that would be *wrong* under the following conditions:
1) You're on a system where pid_t is long
2) sizeof(long) > sizeof(int) (Say, for arg, that 64 > 32)
3) A pid was actually greater than 4GB.
The printf would print only the low order 32 bits.
Then why not printf("My pid is %ld\n", (unsigned long) getpid()); ?
Cheers
seb
--
/ sebastian seb hans \ www.crosswinds.net/~sebh / attention this msg \
| student of comp sci \ yes is no and no is ns / will destroy itself |
\ techn univ of munich \ ha...@in.tum.de / in one second .. rip /
Because in order to know that, you'd have had to delve into the include
files on the system in question. The point of this thread is not that it
can't be done, but rather that doing so requires monkeying around with
details that should not be user visible (i.e., you should not ever have to
look inside the include files).
>>> 2) sizeof(long) > sizeof(int) (Say, for arg, that 64 > 32)
>>> 3) A pid was actually greater than 4GB.
[-]
Yes, if sizeof( pid_t ) > sizeof( unsigned long ) you're toast, but
how realistic is this ? Still if it bothers you and yes, I know many
applications out there were never meant to run around 2000, you can
still guard against it using some #if ... #endif construct.
>>> The printf would print only the low order 32 bits.
>>
>>Then why not printf("My pid is %ld\n", (unsigned long) getpid()); ?
>
>Because in order to know that, you'd have had to delve into the include
>files on the system in question. The point of this thread is not that it
>can't be done, but rather that doing so requires monkeying around with
>details that should not be user visible (i.e., you should not ever have to
>look inside the include files).
[-]
No and BTW %lu, not %ld. Using (unsigned long)getpid() is going to work
as pid_t is an integral type, see the Unix98 specification and as long
as its size is less or equal to the one of an unsigned long.
Since pid_t is not an intrinsic type but a typedef it *can't* be larger
than one.
C++ knows of long long now, but whether this is the case in the latest
C standard .. not sure as for the later I haven't got the last and
official version. Still if so, then the solution is obvious, isn't it ?
Unix98 defines pid_t as a *signed* integral type, actually. Makes sense
of course as eg. fork() needs to be able to return -1.
Sorry,