1 more doubt !

M

maadhuu

firstly, i am thankful to all those who answered the 1st set of doubts. And
i am not yet enlightened to that extent , coz ' i keep getting doubts.

is the following defined in the language ??
int main()
{
int a = 1;
int *p = &a;
p++;
printf("%d",*p);
return 0;
}

thanking you,
ranjan.
 
W

Walter Roberson

is the following defined in the language ??
int main()

You should use int main(void) to be consistant with the C standard.
{
int a = 1;
Valid.

int *p = &a;
Valid.


Valid.

printf("%d",*p);

Not valid. It is legal for an object pointer to point one location
past the end of the object, but it is not legal to dereference the
pointer so formed.
 
R

Robert Gamble

maadhuu said:
firstly, i am thankful to all those who answered the 1st set of doubts. And
i am not yet enlightened to that extent , coz ' i keep getting doubts.

is the following defined in the language ??
int main()

this should be "int main (void)"
{
int a = 1;
int *p = &a;

So far so good.

What you are doing here is advancing the pointer to point to the space
right after the location of a. This is well-defined as a special case,
p+=2 would be undefined behavior.
printf("%d",*p);

return 0;
}

Robert Gamble
 
D

David Resnick

Robert said:
this should be "int main (void)"


So far so good.


What you are doing here is advancing the pointer to point to the space
right after the location of a. This is well-defined as a special case,
p+=2 would be undefined behavior.

Why is it well defined?
Section 6.5.6 of the C99 standard (Additive operators) says

"Moreover, if the expression P points to the last element of an
array object, the expression (P)+1 points one past the last
element of the array object"

I note that a is not an array object, so p doesn't point to one...
Am I confused here?
You forgot to "#include <stdio.h>".
Dereferencing p here is undefined behavior.

If it weren't for the deferencing problem, probably wants to be
printf("%d\n", *p);
Without the newline, you may not see anything.

-David
 
W

Walter Roberson

Why is it well defined?
Section 6.5.6 of the C99 standard (Additive operators) says
"Moreover, if the expression P points to the last element of an
array object, the expression (P)+1 points one past the last
element of the array object"
I note that a is not an array object, so p doesn't point to one...
Am I confused here?

C89 3.3.6

For the purposes of these operators, a pointer to a nonarray object
behaves the same as a pointer to the first element of an array of
length one with a typoe of the object as its element type.
 
M

maadhuu

thanx,
but printing just p, is valid right ???
and also one more doubt .
is a ++i ; valid ??? and one more doubt .

int i = 10;
int a = ++i + ++i;
is this also valid ??? because i++ + i++ is invalid ,but there, the side
effects are present ,and here there shouldn't be any side effects .
 
M

maadhuu

also, i had the same doubt :

Moreover, if the expression P points to the last element of an
array object, the expression (P)+1 points one past the last
element of the array object .

as was quoted by Mr David from
Section 6.5.6 of the C99 standard (Additive operators)

so, does that p++ apply only to arrays or to single objects too ?
ranjan.
 
I

Irrwahn Grausewitz

Please preserve some context when posting replies.
thanx,
but printing just p, is valid right ???
and also one more doubt .

Question. You have questions, not doubts.
is a ++i ; valid ??? and one more doubt .


ITYM: a = ++i;
int i = 10;
int a = ++i + ++i;
is this also valid ??? because i++ + i++ is invalid ,but there, the side
effects are present ,and here there shouldn't be any side effects .

++i has the obvious side effect of incrementing i. Above assignments
invoke undefined behaviour for the very same reasons as the examples
you posted in the other thread. And would you, please, read the FAQ,
as I already suggested?

Best regards
 
D

David Resnick

Walter said:
C89 3.3.6

For the purposes of these operators, a pointer to a nonarray object
behaves the same as a pointer to the first element of an array of
length one with a typoe of the object as its element type.
--

I see now, thanks.

-David
 
K

Keith Thompson

maadhuu said:
firstly, i am thankful to all those who answered the 1st set of doubts. And
i am not yet enlightened to that extent , coz ' i keep getting doubts.

is the following defined in the language ??
int main()
{
int a = 1;
int *p = &a;
p++;
printf("%d",*p);
return 0;
}

No.

First, calling printf() without a prototype invokes undefined behavior
(though it's relatively unlikely to cause any visible problems). Add
"#include <stdio.h>" to the top of your program.

The declaration "int main()" is valid, but "int main(void)" is better
and more explicit.

It's implementation-defined whether you need a newline at the end of
your output. Change "%d" to "%d\n".

Finally (and this is your real problem), after "p++;", p points to a
nonexistent object just after a. You're allowed to create a pointer
just past the end of a real object, but any attempt to dereference
such a pointer invokes undefined behavior.
 
K

Keith Thompson

C89 3.3.6

For the purposes of these operators, a pointer to a nonarray object
behaves the same as a pointer to the first element of an array of
length one with a typoe of the object as its element type.

Presumably "typoe" was a typoe.
 
E

Emmanuel Delahaye

N

Novitas

firstly, i am thankful to all those who answered the 1st set of doubts. And
i am not yet enlightened to that extent , coz ' i keep getting doubts.
is the following defined in the language ??
int main()
{
int a = 1;
int *p = &a;
p++;
printf("%d",*p);
return 0;

}

thanking you,
ranjan.

You are clearly in the realm of undefined behavior. And I mean
undefined in all the senses I alluded to in my earlier replies to your
earlier query.

Others have correctly pointed out the issues with your program example
above.

Now I have a question (a mildly burning curiousity actually): What
would you EXPECT such a program to do?

That is, what do YOU think the program means and what answer are you
anticipating?

Or to put it another way, why do you think such a program would be
valid or produce predictable results?
 
A

August Karlstrom

Robert said:
this should be "int main (void)"




So far so good.




What you are doing here is advancing the pointer to point to the space
right after the location of a. This is well-defined as a special case,
p+=2 would be undefined behavior.

How come p += n isn't allowed for n > 1? As long as no dereference takes
place I can't see any problems with that.


August
 
P

Peter Nilsson

August said:
How come p += n isn't allowed for n > 1? As long as no dereference takes
place I can't see any problems with that.

"Because that's what the standard says." :)

The reason the standard says this is because it is catering for
machines
that can trap purely on the calculation of an invalid address. Also,
there
are segmented architectures where p + n - n may not yield the original
address if n would put the address beyond 'one byte beyond' the
object's
memory.

Conforming implementations on such architectures must still function
for
'one byte beyond' situation, but they need not do more than that.
 
W

Walter Roberson

Robert Gamble wrote:
How come p += n isn't allowed for n > 1? As long as no dereference takes
place I can't see any problems with that.

Segment + offset architectures. Maximum implementation object size
equals maximum segment offset minus 1; after that, p+n becomes
officially undefined behaviour and so implementations are allowed to
wrap the offset (that being as good a choice as any for undefined
behaviour.)

To put it another way, pointer -arithmetic- is only guaranteed
up to one location past the object.

Keep in mind for this purpose that pointers to different types need not
be miscible. The int* with arithmetic value 10000 might point to
a different location than the double* which happens to have
arithmetic value 10000 . Certain conversions through char*
and void* are well defined, but those conversions do not
presume a single linear address space and are defined in such a way
that it is acceptable to "lose track" of the original value if
one converts from a pointer with looser alignment requirements
to a pointer with stricter alignment requirements.
 
J

Jack Klein

You should use int main(void) to be consistant with the C standard.

No version of the C standard requires anything inside the parentheses
in the definition of a function accepting no arguments. This is
perfectly legal even in C99. Implicit int is gone, so these are not
legal:

main()
main(void)
main(int agrc, char **argv)

The only difference between:

int main()

....and:

int main(void)

....is that the latter provides a prototype. And that only provides
actual added value in the very rare program that happens to call
main() recursively.
 
P

pete

Jack said:
No version of the C standard requires anything inside the parentheses
in the definition of a function accepting no arguments. This is
perfectly legal even in C99. Implicit int is gone, so these are not
legal:

main()
main(void)
main(int agrc, char **argv)

The only difference between:

int main()

...and:

int main(void)

...is that the latter provides a prototype. And that only provides
actual added value in the very rare program that happens to call
main() recursively.

N869
6.11.4 Function declarators
The use of function declarators with empty parentheses
(not prototype-format parameter type declarators) is an
obsolescent feature.
 
W

Walter Roberson

No version of the C standard requires anything inside the parentheses
in the definition of a function accepting no arguments. This is
perfectly legal even in C99.

Not for main it isn't.

[C89] 2.1.2.2.1 Program Startup

The function called at program startup is named main. The
implementation declares no prototype for this function. It can be
defined with no parameters:

int main(void) { /*...*/ }

or with two parameters (referred to here as argc and argv, though
any names may be used, as they are local to the function in which they
are declared):

int main(int argc, char *argv[]) { /*...*/ }


Notice that C89 did not list the possibility of int main()

In general, the parameter passing mechanism for a function with
no arguments may be different than the parameter passing mechanism
for a function with two arguments, and that passing extra arguments
to non-vararg functions is UB. Therefor, the implementation may have
to special-case handling of main() -- and the standard only requires
that those two particular forms be handled. The declaration of
main() is special in the standard, and one cannot presume to be true
any declaration rules that are required for other routines.
 
I

Irrwahn Grausewitz

Jack Klein said:
No version of the C standard requires anything inside the parentheses
in the definition of a function accepting no arguments. This is
perfectly legal even in C99. Implicit int is gone, so these are not
legal:

main()
main(void)
main(int agrc, char **argv)

The only difference between:

int main()

...and:

int main(void)

...is that the latter provides a prototype. And that only provides
actual added value in the very rare program that happens to call
main() recursively.

According to the standard (C99 5.1.2.2.1p1), only the following
two definitions of main are guaranteed to be valid:

int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }

Of course, other definitions may be allowed by a particular
implementation, but that's not the point.

Best regards
 

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

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top