Pointer arithmetic

S

Simon Biber

Morris said:
main() (in (e-mail address removed)) said:
| 2) My second question is ,
|
| #include<stdio.h>
|
| int main(void)
| {
| int *p = (int*) 1;
| int *q = (int*) 2000;
| printf("%d\n",(q-1));
| printf("%d\n",(q-p));
| }

This code has undefined behaviour. The pointers do not point to valid
int objects. In addition, p is probably not aligned correctly for int.

Attempting to subtract 1 from q is undefined behaviour since q does not
point to a valid int object nor array of int nor allocated memory. The
same goes for subtracting p from q, but in addition the alignment issues
may cause problems.

Attempting to print a pointer to int through an int specifier in printf
is also undefined behaviour. Pointers and ints often have different
sizes, and may even be passed in different locations.

In practise though, you seem to have got results along the lines of
2000 - 1 * 4 == 1996
and
(2000 - 1) / 4 == 499
where 4 was sizeof(int) on your machine.

That should make it clear where the 499 came from.
| output:
| 1996
| 499
|
| I can understand why the first printf outputs 1996, (because when
| you decrement an integer pointer, it points to the prevoius
| integer which is four bytes offset from the current location)
| But i cannot understand why second printf outputs 499 ?
| Can anyone throw light on this one ?

My results were:
1999
1999

That may have been because you ran it on an unusual system where the
size of int is 1 byte. On such a system, a byte must be at least 16 bits
wide.
 
J

Jordan Abel

2006-08-21 <[email protected]>,
"The function "main" is unique in that it can *only* have one of two
different signatures. "

Nope AFAIK, main can have 3 different signatures

1. main (void)
2. main (int argc, char *argv[])
3. main (int argc, char *argv[], char *envp[])

If you google for N1124 and read section 5.1.2.2.1 you'll
see that only the first 2 forms are valid although the third
may also work on many platforms. The third may appear
in some Unix standard but I'm not sure.

Actually, environment manipulation, while present in the unix standards,
is quite cut down compared to the full "historic" environment. There is
no putenv, no envp, and IIRC no environ, only getenv and setenv.
 
J

Jordan Abel

2006-08-21 said:
(There are other ways to "make it work" that depend on the target
system, and most real compilers use one of those, since those are
usually easier.)

I.e. some variation of "pass all three^Wtwo arguments anyway, our ABI
doesn't care" - or if it does, turn main(void) into a function that
takes two arguments and throws them away, or create a stub
main(int,char**) function that ignores its arguments and calls
main(void).
 
D

Dave Thompson

<OT>
Function overloading? It means that you will write
more than one function, but the caller doesn't have
to know this; it'll look like one function.
</OT>
Although this allows only(?) variation among the defined overloads.
And it isn't the same actual function though it is the same name.

Also defaulted parameters like
void func (int a, int b = 1, int c = 2, int d = 3);
which allows variation over prefixes of the defined sequence.

And you can even do both -- overloads each with defaults --
although you'll usually confuse yourself and your maintainer(s) (if
different from yourself) even if not the compiler.

And finally in C++ you can still use C-style <stdarg.h> or its unevil
twin <cstdarg>. With the same features and problems.

- David.Thompson1 at worldnet.att.net
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top