Code Comments
Programming Forum and web based access to our favorite programming groups.In article <4ccdc3c0-8674-4425-8567-527a20e033a8@i7g2000prf.googlegroups.com>, Sanchit <sanchitgupta.1@gmail.com> wrote: > On Mar 18, 4:35 am, gordonb.fy...@burditt.org (Gordon Burditt) wrote: > > Thnx... But i dont agree with ur 2nd point.. i printf pid_t type like > intergers only by using %d and it is working fine... Whether it works on any particular implementation depends on whether sizeof(int) == sizeof(pid_t). If sizeof(pid_t) > sizeof(int), it might work for small PIDs if byte order happens to match up properly. If you want to be sure that it gets passed properly, you need to declare and cast properly. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE don't copy me on replies, I'll read them in the group ***
Post Follow-up to this messageSanchit wrote:
> Thnx... But i dont agree with ur 2nd point.. i printf pid_t type like
> intergers only by using %d and it is working fine...
I used to make this sort of mistake all the time until finally it
caused a program of mine to crash unexpectedly and I had to spend
hours and hours tracking it down.
I was doing this on another platform that had types like Int16 and
Int32, and I passed these to a function much like printf() (one
that takes a variable number of arguments). It "worked" until I
changed some compiler options and some of my variables changed
sizes as a result. Then it just started crashing.
That's because the compiler generates machine code for the printf()
implementation, and that implementation assumes the arguments (that
correspond to %d) are a certain size. It has to know the size of
them so that it can move them around, adjust the stack pointer, and
so on. Then the compiler also generates code when you *call* printf(),
and that code has to also move around values and adjust the stack
pointer and stuff. When the values are not the same size, the stack
pointer is off, or garbage bits are copied, or something else will
go wrong, and your program will crash spectacularly.
If you'd like to cause this kind of problem for yourself or someone
else in the future, go ahead and write stuff like this:
pid_t foo;
printf("%d", foo); /* I like writing flaky code */
But if you don't want to cause headaches for yourself and everyone,
you should instead write code like this:
pid_t foo;
printf("%d", (int) foo);
Or like this:
pid_t foo;
printf("%ld", (long) foo);
Note that the last two examples aren't absolutely guaranteed to
print anything meaningful, in case pid_t is larger than a long.
But they will at least pass values to the function in a way that
printf() can run without crashing.
The general rule is, when you are using "%d" with printf(), always
either use a variable or expression whose type is already for sure
int, or cast the expression to an int. The compiler is relying on
YOU to give it the correct type information. It has no other way
of knowing. The only information about the type that printf()
expects is the "%d" in the string, and the compiler cannot interpret
that. So it must look at the type of the expression you give as
an argument. A similar rule is to always make sure the expression's
type is long if you use "%ld". (And 'double' for "%f" and so on.)
- Logan
Post Follow-up to this messageOn Mar 18, 6:51 pm, Logan Shaw <lshaw-use...@austin.rr.com> wrote: > Then the compiler also generates code when you *call* printf(), > and that code has to also move around values and adjust the stack > pointer and stuff. When the values are not the same size, the stack > pointer is off, or garbage bits are copied, or something else will > go wrong, and your program will crash spectacularly. Just to clarify, he means (I hope) that the stack pointer will be off or garbage bits will be copied in the implementation of 'printf'. The compiler will not copy garbage bits or any such thing. DS
Post Follow-up to this message"jason.cipriani@gmail.com" <jason.cipriani@gmail.com> writes: >On Mar 18, 5:48 am, Rainer Weikusat <rweiku...@mssgmbh.com> wrote: >Does it say somewhere that pid_t will never be a pointer type, or some >other type, like a float (which, while strange, is fine since it's >hidden behind the typedef)? If it can be, then the discussion of using >longs or whatever interchangeably with pid_t's is moot. It needs to be a signed airthmetic type: If pid is negative but not (pid_t)-1, sig will be sent to all processes whose process group ID is equal to the abso- lute value of pid and for which the process has permission to send a signal. Since it needs to be used in comparisons it can't really be float... Casper -- Expressed in this posting are my opinions. They are in no way related to opinions held by my employer, Sun Microsystems. Statements on Sun products included here are not gospel and may be fiction rather than truth.
Post Follow-up to this messageLogan Shaw <lshaw-usenet@austin.rr.com> writes:
>Or like this:
> pid_t foo;
> printf("%ld", (long) foo);
>Note that the last two examples aren't absolutely guaranteed to
>print anything meaningful, in case pid_t is larger than a long.
>But they will at least pass values to the function in a way that
>printf() can run without crashing.
But only if the actual value of the pid is larger than the
value which can be represented in int or long.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Post Follow-up to this messageOn Mar 18, 12:09 pm, "jason.cipri...@gmail.com" <jason.cipri...@gmail.com> wrote: > "The implementation shall support one or more programming environments > in which the widths of blksize_t, pid_t, size_t, ssize_t, suseconds_t, > and useconds_t are no greater than the width of type long." > If you take that to mean that *all* supported "programming > environments" have pid_t with width no greater than the width of type > long, then it *is* save to store pid_t's in a long. Is there something > that indicates that it's not? That's definitely not what it says. It says such an environment must be supported, not that it must be the only one supported or that it must be the default. Storing a pid_t in a long may limit which environments you can use. > If that's the case the only two issues with using long instead of > pid_t are: > > 1) If that standard changes some day, and > > 2) Using pid_t clearly indicates that the variable, function > parameter, etc., is meant to hold a process ID, and not some arbitrary > integer with another meaning. Saves on documentation. What about cases where you need a pointer to something that holds a pid, like posix_spawn? What about cases where you need to pass a PID through a function with a '...' definition? DS
Post Follow-up to this messageWilliam Ahern <william@wilbur.25thandClement.com> writes: > Rainer Weikusat <rweikusat@mssgmbh.com> wrote: > > > The counter example is to the implicit assumption in your response that th e > only interfaces for which pid_t is applicable return its _value_ as throug h > an expression. With that assumption in mind, you then explained the > difference between values and representations. What you believe about me is in your mind.
Post Follow-up to this messageRainer Weikusat <rweikusat@mssgmbh.com> wrote: > William Ahern <william@wilbur.25thandClement.com> writes: <snip> > > What you believe about me is in your mind. Neo?
Post Follow-up to this message>> >And I think my question is misunderstood. I just want you to tell me > >Thnx... But i dont agree with ur 2nd point.. i printf pid_t type like >intergers only by using %d and it is working fine... Try it on a system where pid_t is long long or larger AND big-endian. Or on a system where sizeof(int) != sizeof(long) and pid_t is long and you are printing 3 integers, with the pid_t being the middle one.
Post Follow-up to this messageDavid Schwartz wrote: > On Mar 18, 6:51 pm, Logan Shaw <lshaw-use...@austin.rr.com> wrote: > Just to clarify, he means (I hope) that the stack pointer will be off > or garbage bits will be copied in the implementation of 'printf'. The > compiler will not copy garbage bits or any such thing. Well, whether the caller is copying garbage bits is sort of a philosophical question: if the caller assigns some meaning to them but the callee doesn't know the meaning, is there really any meaning there? In some hypothetical world where the callee understood what the caller meant, the information is not garbage. But that hypothetical by definition doesn't exist. The bits have a meaning according to the specs of some calling convention, but that meaning is only relevant as a set of rules that help a programmer use tools to produce correct code (where the caller and callee match up). Although I suppose you could argue that the state is meaningful when you step through with a debugger, and maybe that does matter. At any rate, the system as a whole will behave in a way which isn't intended. :-) - Logan
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.