By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,312 Members | 1,877 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,312 IT Pros & Developers. It's quick & easy.

function return pointer of int?

P: n/a
Hi all,

I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?

int * get_p_t(int t) {
return &t;
}

int main()
{
printf("v1\n");
int t = 5;
int * p_t[2];

p_t[0] = &t; // right
p_t[1] = get_p_t(t); //wrong

return 0;
}

Best regards,
Davy
Nov 5 '08 #1
Share this Question
Share on Google+
34 Replies


P: n/a
Davy wrote:
Hi all,

I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?

int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

--
Ian Collins
Nov 5 '08 #2

P: n/a
On Nov 5, 2:49*pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
* * return &t;
}

t is effectively a local variable in get_p_t. *So the address you return
will be invalid after the function returns.
Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?
>
--
Ian Collins
Nov 5 '08 #3

P: n/a
Davy wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Davy wrote:
>>Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?
You can't. You get the address of where t was.

--
Ian Collins
Nov 5 '08 #4

P: n/a
On Nov 5, 12:12*pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
* * return &t;
}
t is effectively a local variable in get_p_t. *So the address you return
will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?

You can't. *You get the address of where t was.

--
Ian Collins
Still he can get a reference or a pointer to t as the input parameter
and return a valid pointer.
Nov 5 '08 #5

P: n/a
Hi

Davy schrieb:
>>int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

But how can I get the address of t in the main() scope, if I want to
use function?
int * get_p_t(int & t) {
return &t;
}

will do the job, but it still makes little sense since you stil may
receive a local address from the caller. At least it should be well
documented the the argument to get_p_t has to be valid at least as long
as the return value is used.
[Only posted to the c++ group]
Marcel
Nov 5 '08 #6

P: n/a
DJ Dharme wrote:
On Nov 5, 12:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Davy wrote:
>>On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?
You can't. You get the address of where t was.

Still he can get a reference or a pointer to t as the input parameter
and return a valid pointer.
Do what?

--
Ian Collins
Nov 5 '08 #7

P: n/a
On 5 Nov, 07:06, Davy <zhushe...@gmail.comwrote:
On Nov 5, 2:49*pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
* * return &t;
}
t is effectively a local variable in get_p_t. *So the address you return
will be invalid after the function returns.

Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?
as Ian Collins said "you can't".

Why do you want to do this? I'm not being awkward if you explain
your larger problem, the context in which you want the address of t
we might be able to suggest a workaround.

int main (void)
{
printf("v1\n");
int t = 5;
int * p_t[2];

p_t[0] = &t;
p_t[1] = get_p_t(t);

/*** you have the address of t by using &t.
why do you want a function to do this? */

return 0;
}

--
Nick Keighley
Nov 5 '08 #8

P: n/a
On Nov 5, 9:31 am, DJ Dharme <donjuandharmap...@gmail.comwrote:
On Nov 5, 12:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Davy wrote:
>>Hi all,
>>I am writing a function, which return the pointer of the int. But it
>>seems to be wrong. Any suggestion?
>>int * get_p_t(int t) {
>> return &t;
>>}
>t is effectively a local variable in get_p_t. So the address you return
>will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?
You can't. You get the address of where t was.
--
Ian Collins

Still he can get a reference or a pointer to t as the input parameter
and return a valid pointer.
Please don't quote signatures. (the text after --)
Also, no, he can't. I think his function is valid, ie this code is
valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)
Nov 5 '08 #9

P: n/a
Davy wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Davy wrote:
>>Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?
int * get_p_int(int *pt) { return pt;}

int main(void)
{
int t;
int *p = get_p_int(&t);
Of course, this is pretty pointless; get_p_int(&t) doesn't get you
anything that &t doesn't already get you. So you might as well writer

int *p = &t;

So, what is the real problem you're trying to solve?
Nov 5 '08 #10

P: n/a
In message <0p*****************@nwrddc02.gnilink.net>, James Kuyper
<ja*********@verizon.netwrites
>Davy wrote:
>On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?

int * get_p_int(int *pt) { return pt;}

int main(void)
{
int t;
int *p = get_p_int(&t);
Of course, this is pretty pointless; get_p_int(&t) doesn't get you
anything that &t doesn't already get you. So you might as well writer

int *p = &t;

So, what is the real problem you're trying to solve?
Understanding the difference between C++ and C? Note the crosspost.

--
Richard Herring
Nov 5 '08 #11

P: n/a
On Nov 5, 8:06 am, Davy <zhushe...@gmail.comwrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
I am writing a function, which return the pointer of the
int. But it seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the
address you return will be invalid after the function
returns.
But how can I get the address of t in the main() scope, if I
want to use function?
Didn't you read what Ian wrote? t doesn't exist except when
you're executing get_p_t. And there's obviously no way to get
the address of something which doesn't exist.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Nov 5 '08 #12

P: n/a
Richard Herring wrote:
In message <0p*****************@nwrddc02.gnilink.net>, James Kuyper
<ja*********@verizon.netwrites
>Davy wrote:
>>On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you
return
will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?

int * get_p_int(int *pt) { return pt;}

int main(void)
{
int t;
int *p = get_p_int(&t);
Of course, this is pretty pointless; get_p_int(&t) doesn't get you
anything that &t doesn't already get you. So you might as well writer

int *p = &t;

So, what is the real problem you're trying to solve?

Understanding the difference between C++ and C? Note the crosspost.
You're right, I didn't notice the cross-post. There is indeed a C++
solution using references:

int *get_p_int(int &t) { return &t;}

Because of the syntactic sugar of references, the C++ version appears
marginally less pointless than the C version, but I think that's mostly
an illusion - the machine code generated for either version should be
functionally equivalent. However, precisely because of the cross-post, I
think that use of C++ references would be inappropriate; the cross-post
implies a desire for a solution that works in either language.
Nov 5 '08 #13

P: n/a
In article <b9**********************************@p31g2000prf. googlegroups.com>,
James Kanze <ja*********@gmail.comwrote:
....
>Didn't you read what Ian wrote? t doesn't exist except when
you're executing get_p_t.
True.
>And there's obviously no way to get
the address of something which doesn't exist.
Not true. The Munsters don't exist, but their address is "1313
Mockingbird Lane". So, it is possible to have the address of something
that doesn't exist. De-referencing such an address does, of course,
lead to undefined behavior.
Nov 5 '08 #14

P: n/a
vi******@gmail.com writes:
[...]
Also, no, he can't. I think his function is valid, ie this code is
valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)
It's "valid" only in the narrow sense that it doesn't violate any
constraint or syntax rule. But "valid" isn't a word I'd apply to a
function that can't be called without invoking undefined behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 5 '08 #15

P: n/a
On Nov 5, 3:00 pm, gaze...@shell.xmission.com (Kenny McCormack) wrote:
In article
<b9b1c923-1dcd-4765-8e7e-7f223a9db...@p31g2000prf.googlegroups.com>,
James Kanze <james.ka...@gmail.comwrote:
...
Didn't you read what Ian wrote? t doesn't exist except when
you're executing get_p_t.
True.
And there's obviously no way to get the address of something
which doesn't exist.
Not true. The Munsters don't exist, but their address is
"1313 Mockingbird Lane".
Only in the imaginary world where they exist.
So, it is possible to have the address of something that
doesn't exist. De-referencing such an address does, of
course, lead to undefined behavior.
First, you can't have an address of something that doesn't
exist. You can perhaps have a pointer whose bit pattern
corresponds to the address where it was, but it's no longer a
valid address, and even copying it is undefined behavior.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34

Nov 5 '08 #16

P: n/a
On Nov 5, 4:26*am, vipps...@gmail.com wrote:
On Nov 5, 9:31 am, DJ Dharme <donjuandharmap...@gmail.comwrote:
On Nov 5, 12:12 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
>Hi all,
>I am writing a function, which return the pointer of the int. Butit
>seems to be wrong. Any suggestion?
>int * get_p_t(int t) {
>* * return &t;
>}
t is effectively a local variable in get_p_t. *So the address you return
will be invalid after the function returns.
Hi Ian, thank you,
But how can I get the address of t in the main() scope, if I want to
use function?
You can't. *You get the address of where t was.
--
Ian Collins
Still he can get a reference or a pointer to t as the input parameter
and return a valid pointer.

Please don't quote signatures. (the text after --)
Also, no, he can't. I think his function is valid, ie this code is
valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)
It only becomes undefined if you try to deref the
pointer that gets returned, because it's a pointer
to a local variable, which has gone out of scope
by the time foo returns. There is no problem with
taking the address, or passing the address around.
But if you try to manipulate things through that
address, you open the gates of undefined.
Socks
Nov 5 '08 #17

P: n/a
Puppet_Sock <pu*********@hotmail.comwrites:
On Nov 5, 4:26*am, vipps...@gmail.com wrote:
[...]
>int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)

It only becomes undefined if you try to deref the
pointer that gets returned, because it's a pointer
to a local variable, which has gone out of scope
by the time foo returns. There is no problem with
taking the address, or passing the address around.
But if you try to manipulate things through that
address, you open the gates of undefined.
(Ok, whose sock-puppet are you?)

You're mistaken. If you have a pointer to an object, and that object
then ceases to exists, then the pointer value becomes indeterminate,
and any attempt to evaluate the pointer invokes undefined behavior.

For example:

int *p = malloc(sizeof *p);
assert(p != NULL); /* just for this example */
free(p);
p; /* undefined behavior */

On most implementations, nothing bad will actually happen; that's just
one possible manifestation of undefined behavior.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 5 '08 #18

P: n/a
Puppet_Sock wrote:
On Nov 5, 4:26�am, vipps...@gmail.com wrote:
....
Also, no, he can't. I think his function is valid, ie this code is
valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)

It only becomes undefined if you try to deref the
pointer that gets returned, because it's a pointer
to a local variable, which has gone out of scope
by the time foo returns. There is no problem with
taking the address, or passing the address around.
But if you try to manipulate things through that
address, you open the gates of undefined.
Dereferencing the pointer is not the only way the behavior can be
undefined.

6.2.4p2: "The value of a pointer becomes indeterminate when the object
it points to reaches the end of its lifetime."

The lifetime of 't' has already ended by the time the function has
returned.

The definition of "indeterminate value" is given in 3.17.2p1: "either
an unspecified value or a trap representation".

Because the value returned by the function could be a trap
representation, any attempt to store it in an object will also have
undefined behavior.

Using the value without storing it in a pointer object would seem to
be safe, but virtually every operation you can perform on a non-null
pointer value other than storing it somewhere, is defined in terms of
the object that it points at. As a result, since no such object exists
any longer, the behavior is implicitly undefined, by reason of the
absence of an applicable definition of the behavior. The standard
explicitly allows for behavior to be implicitly undefined.
Nov 5 '08 #19

P: n/a
On Wed, 05 Nov 2008 01:26:57 -0800, vippstar wrote:
Please don't quote signatures. (the text after --) Also, no, he can't. I
think his function is valid, ie this code is valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior, since
the object pointed to by the pointer is over its lifetime, and the
pointer becomes indeterminate. (either unspecified value or trap
representation)
You are allowed to call foo. You are even allowed to use its return value
in limited ways (such as comparisons). You are not allowed to store foo's
result in an object, or dereference it.

The behaviour dealing with trap representations is only undefined if you
store them in an object ("produced by a side effect that modifies all or
any part of the object by an lvalue expression that does not have
character type"), or read them from an object ("read by an lvalue
expression that does not have character type"). In this code, if you call
foo and discard its result, the return value is never stored in or read
from an object.

Actually, I'm not sure how the return value could be a trap representation
at all, since it's a value, and the concept of trap representations
applies to objects, but 6.3.2.2p5 (conversions of integers to pointers) is
a clear example of when a non-lvalue expression may explicitly be a trap
representation.
Nov 5 '08 #20

P: n/a
On Wed, 05 Nov 2008 18:17:51 +0000, Harald van Dijk wrote:
On Wed, 05 Nov 2008 01:26:57 -0800, vippstar wrote:
>Please don't quote signatures. (the text after --) Also, no, he can't.
I think his function is valid, ie this code is valid:

int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior, since
the object pointed to by the pointer is over its lifetime, and the
pointer becomes indeterminate. (either unspecified value or trap
representation)

You are allowed to call foo. You are even allowed to use its return
value in limited ways (such as comparisons). You are not allowed to
store foo's result in an object, or dereference it.

The behaviour dealing with trap representations is only undefined if you
store them in an object ("produced by a side effect that modifies all or
any part of the object by an lvalue expression that does not have
character type"), or read them from an object ("read by an lvalue
expression that does not have character type"). In this code, if you
call foo and discard its result, the return value is never stored in or
read from an object.

Actually, I'm not sure how the return value could be a trap
representation at all, since it's a value, and the concept of trap
representations applies to objects, but 6.3.2.2p5 (conversions of
integers to pointers) is a clear example of when a non-lvalue expression
may explicitly be a trap representation.
I would like to add that when I posted this, I hadn't noticed the cross-
post. What I said applies to C99; C90 is different here. I do not know
whether C++ in its current form follows C90, C99, or has entirely
different rules regarding indeterminate values.
Nov 5 '08 #21

P: n/a
On Nov 5, 7:17*pm, Harald van Dijk <true...@gmail.comwrote:
On Wed, 05 Nov 2008 01:26:57 -0800, vippstar wrote:
Please don't quote signatures. (the text after --) Also, no,
he can't. I think his function is valid, ie this code is
valid:
int *foo(int i) { return &i; }
However even evaluating foo(anything) invokes undefined
behavior, since the object pointed to by the pointer is over
its lifetime, and the pointer becomes indeterminate. (either
unspecified value or trap representation)
You are allowed to call foo. You are even allowed to use its
return value in limited ways (such as comparisons).
Are you sure? It's certainly not the case in C++, and I didn't
think it was the case in C; any use of the pointers value
(lvalue to rvalue conversion) is undefined behavior, so
comparisons are out.

If the invalid pointer is an lvalue expression, you can do
anything with it that doesn't require an lvalue to rvalue
conversion. For example, take its address, or in C++, bind it
to a reference. Which means that you can also memcpy and memcmp
it. (In the actual example, of course, the pointer isn't an
lvalue, so this is irrelevant.)
You are not allowed to store foo's result in an object, or
dereference it.
The behaviour dealing with trap representations is only
undefined if you store them in an object ("produced by a side
effect that modifies all or any part of the object by an
lvalue expression that does not have character type"), or read
them from an object ("read by an lvalue expression that does
not have character type"). In this code, if you call foo and
discard its result, the return value is never stored in or
read from an object.
Is this a change in C99? It's not the case in C++, nor was it
the case in C90.
Actually, I'm not sure how the return value could be a trap
representation at all, since it's a value, and the concept of
trap representations applies to objects, but 6.3.2.2p5
(conversions of integers to pointers) is a clear example of
when a non-lvalue expression may explicitly be a trap
representation.
It looks like the attempts to clean up a rather vague concept
accidentally went too far. (In C++, this wouldn't cause a
problem, because you return a temporary object, and of course,
this object can have a trapping representation, in which case,
you trap. Not sure about C in this regard.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 5 '08 #22

P: n/a
On Wed, 05 Nov 2008 10:55:16 -0800, James Kanze wrote:
On Nov 5, 7:17*pm, Harald van Dijk <true...@gmail.comwrote:
>The behaviour dealing with trap representations is only undefined if
you store them in an object ("produced by a side effect that modifies
all or any part of the object by an lvalue expression that does not
have character type"), or read them from an object ("read by an lvalue
expression that does not have character type"). In this code, if you
call foo and discard its result, the return value is never stored in or
read from an object.

Is this a change in C99? It's not the case in C++, nor was it the case
in C90.
Yes, this is what 6.2.6.1p5 says:
"Certain object representations need not represent a value of the object
type. If the stored value of an object has such a representation and is
read by an lvalue expression that does not have character type, the
behavior is undefined. If such a representation is produced by a side
effect that modifies all or any part of the object by an lvalue
expression that does not have character type, the behavior is
undefined.[*] Such a representation is called a trap representation."

C99 has dropped C90's wording for reading indeterminate values, and
replaced it with this.

Thanks for a bit of info on C++'s approach to this.
Nov 5 '08 #23

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Puppet_Sock <pu*********@hotmail.comwrites:
>On Nov 5, 4:26*am, vipps...@gmail.com wrote:
[...]
>>int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)

It only becomes undefined if you try to deref the
pointer that gets returned, because it's a pointer
to a local variable, which has gone out of scope
by the time foo returns. There is no problem with
taking the address, or passing the address around.
But if you try to manipulate things through that
address, you open the gates of undefined.

(Ok, whose sock-puppet are you?)

You're mistaken. If you have a pointer to an object, and that object
then ceases to exists, then the pointer value becomes indeterminate,
and any attempt to evaluate the pointer invokes undefined behavior.
What about not doing anything with it?

foo(0);

It's not being assigned to anything, compared to anything, computed
with, dereferenced, or basically anything that could be said to be
"evaluating" the pointer?

Phil
--
We must respect the other fellow's religion, but only in the sense and to the
extent that we respect his theory that his wife is beautiful and his children
smart. -- Henry Louis Mencken (1880-1956), American editor and critic
Nov 6 '08 #24

P: n/a
Phil Carmody <th*****************@yahoo.co.ukwrites:
Keith Thompson <ks***@mib.orgwrites:
>Puppet_Sock <pu*********@hotmail.comwrites:
>>On Nov 5, 4:26*am, vipps...@gmail.com wrote:
[...]
>>>int *foo(int i) { return &i; }

However even evaluating foo(anything) invokes undefined behavior,
since the object pointed to by the pointer is over its lifetime, and
the pointer becomes indeterminate. (either unspecified value or trap
representation)

It only becomes undefined if you try to deref the
pointer that gets returned, because it's a pointer
to a local variable, which has gone out of scope
by the time foo returns. There is no problem with
taking the address, or passing the address around.
But if you try to manipulate things through that
address, you open the gates of undefined.

(Ok, whose sock-puppet are you?)

You're mistaken. If you have a pointer to an object, and that object
then ceases to exists, then the pointer value becomes indeterminate,
and any attempt to evaluate the pointer invokes undefined behavior.

What about not doing anything with it?

foo(0);

It's not being assigned to anything, compared to anything, computed
with, dereferenced, or basically anything that could be said to be
"evaluating" the pointer?
When an expression statement is executed, the expression is evaluated
and its result is discarded. An implementation might reasonably store
the result in an address register; the act of storing an invalid
address in an address register might cause a trap.

But Harald made a very interesting point. The pointer value returned
by foo is indeterminate, meaning that it's either an unspecified value
or a trap representation. But a trap representation is not a value.
His argument is that there's no representation (at least as far as the
language semantics are concerned) until and unless the value is stored
in an object.

On the other hand, this means that the standard's definition of an
indeterminate *value* as either an unspecified value or a trap
*representation* doesn't make a whole lot of sense.

I'm not sure how this should be resolved.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 6 '08 #25

P: n/a
On 115, 3ʱ06, Davy <zhushe...@gmail.com>wrote:
On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?


--
Ian Collins- ر -

- ʾõ -


void *fun(int i)
{
void *p = &i;
p += (1<<5) + 4;

return p;
}
Nov 6 '08 #26

P: n/a
On Wed, 5 Nov 2008 22:30:03 -0800 (PST), ba**********@163.com wrote:
>On 11??5??, ????3??06??, Davy <zhushe...@gmail.comwrote:
>On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.comwrote:
Davy wrote:
Hi all,
I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?
int * get_p_t(int t) {
return &t;
}
t is effectively a local variable in get_p_t. So the address you return
will be invalid after the function returns.

Hi Ian, thank you,

But how can I get the address of t in the main() scope, if I want to
use function?


--
Ian Collins- ?????????????? -

- ?????????????? -

void *fun(int i)
{
void *p = &i;
p += (1<<5) + 4;

return p;
}
What do you think this accomplishes?

Your first executable statement contains a constraint violation. If
you ignore that (some compilers do as an extension), it invokes
undefined behavior if sizeof(int) < 36. If you have a system with
really large int, then the value returned still becomes indeterminate
as soon as the function returns.

--
Remove del for email
Nov 6 '08 #27

P: n/a
On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.comwrote:
On Wed, 5 Nov 2008 22:30:03 -0800 (PST), baichuan0...@163.com wrote:
[...]
void *fun(int i)
{
void *p = &i;
p += (1<<5) + 4;
return p;
}
What do you think this accomplishes?
Your first executable statement contains a constraint violation.
I'm not sure what you mean by the "first executable statement".
The definition of p (with its initialization) definitely
generates executable code, and is executed. And there's no
problem with this statement; it is legal and well defined, and
must work in any implementation.

The second statement, of coruse, is ill formed. Pointer
arithmetic is illegal on pointers to void. This is a
constraint violation, which requires a diagnostic.
If you ignore that (some compilers do as an extension), it
invokes undefined behavior if sizeof(int) < 36.
If you have invoked the compiler in a non-conformant mode, what
it does is defined by the compler. If a compiler accepts the
second statement above, you can no longer argue about the code
with regards to the language. For that matter, technically,
once the compiler has issued the diagnostic, it has fulfilled
its obligation, and the rest is undefined behavior. (QoI
issues, of course, introduce additional constraints, but as far
as the standard is concerned, a compiler that reformats your
hard disk anytime you try to compile an ill-formed program is
compliant. The compiler could even document that it's
diagnostic message was to turn on the light of the hard disk
drive for an indeterminate time---I don't think that the
standard formally requires the diagnostic to be text.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Nov 6 '08 #28

P: n/a
Keith Thompson wrote:
....
But Harald made a very interesting point. The pointer value returned
by foo is indeterminate, meaning that it's either an unspecified value
or a trap representation. But a trap representation is not a value.
His argument is that there's no representation (at least as far as the
language semantics are concerned) until and unless the value is stored
in an object.
More to the point, the only cases associated with trap representations
where the C standard explicitly says the behavior is undefined are the
creation of a trap representation in an object by any method other than
use of an lvalue of character type, or by attempting to access the value
of an object that already contains a trap representation.
On the other hand, this means that the standard's definition of an
indeterminate *value* as either an unspecified value or a trap
*representation* doesn't make a whole lot of sense.
I think that the fundamental problem was the decision of the C committee
to define an indeterminate "value" as including, as one possibility, a
trap "representation". It should probably have been called an
"indeterminate representation", but that would have required rewriting
every place in the standard that currently uses "indeterminate value",
and the rewrite would be substantially clumsier than the current wording.

In particular, such a change would make it more complicated to describe
what is going wrong in this particular program: returning a pointer from
a function that becomes invalid precisely because of the fact the
function has returned. Maybe we also need the concept of a "trap value",
distinct from the idea of a "trap representation"?
Nov 6 '08 #29

P: n/a
James Kanze <ja*********@gmail.comwrites:
On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.comwrote:
>On Wed, 5 Nov 2008 22:30:03 -0800 (PST), baichuan0...@163.com wrote:

[...]
>void *fun(int i)
{
void *p = &i;
p += (1<<5) + 4;
return p;
}
>What do you think this accomplishes?
>Your first executable statement contains a constraint violation.

I'm not sure what you mean by the "first executable statement".
The definition of p (with its initialization) definitely
generates executable code, and is executed. And there's no
problem with this statement; it is legal and well defined, and
must work in any implementation.
The cross-post is confusing matters (as always!).

In C there is a clear distinction between declarations and statements,
both in the formal syntax as well as in the less formal text of the
standard, so "the first statement" refers unambiguously to the
increment of p (and the extra "executable" is redundant). In C++, as
you know, there is a "declaration statement" so the distinction is
lost. Barry is presumably assuming the code is C.

--
Ben.
Nov 6 '08 #30

P: n/a
On Nov 6, 3:44*pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
James Kanze <james.ka...@gmail.comwrites:
On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.comwrote:
On Wed, 5 Nov 2008 22:30:03 -0800 (PST), baichuan0...@163.com wrote:
* * [...]
void *fun(int i)
{
* *void *p = &i;
* *p += (1<<5) + 4;
* *return p;
}
What do you think this accomplishes?
Your first executable statement contains a constraint violation.
I'm not sure what you mean by the "first executable
statement". The definition of p (with its initialization)
definitely generates executable code, and is executed. *And
there's no problem with this statement; it is legal and well
defined, and must work in any implementation.
The cross-post is confusing matters (as always!).
Especially as it concerns an area in which C and C++ try to be
identical---all too often using different words to (hopefully)
say the same thing.
In C there is a clear distinction between declarations and
statements, both in the formal syntax as well as in the less
formal text of the standard, so "the first statement" refers
unambiguously to the increment of p (and the extra
"executable" is redundant). *In C++, as you know, there is a
"declaration statement" so the distinction is lost. *Barry is
presumably assuming the code is C.
I'd missed that difference. Historically, of course, it made
sense, since you couldn't mix declarations and (other)
statements.

My main point still holds, of course: no C or C++ compiler will
accept pointer arithmetic on an incomplete type (and void is an
incomplete type). The code simply won't compile.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique oriente objet/
Beratung in objektorientierter Datenverarbeitung
9 place Smard, 78210 St.-Cyr-l'cole, France, +33 (0)1 30 23 00 34
Nov 6 '08 #31

P: n/a
James Kanze wrote:
....
My main point still holds, of course: no C or C++ compiler will
accept pointer arithmetic on an incomplete type (and void is an
incomplete type). The code simply won't compile.
More accurately: no fully conforming compiler for either language will
accept such code without first issuing a diagnostic. A number of
popular compilers will indeed accept pointer arithmetic on void*,
which is performed as if it were char*. As long as they also issue the
mandatory diagnostic message, they can do so while remaining fully
conforming.
Nov 6 '08 #32

P: n/a
Michael <mi*****@michaeldadmum.no-ip.orgwrites:
[...]
change
int * get_p_t(int t) {
to
int * get_p_t(int&t) {
Not in C (note the cross-post).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 7 '08 #33

P: n/a
James Kanze <ja*********@gmail.comwrites:
[...]
My main point still holds, of course: no C or C++ compiler will
accept pointer arithmetic on an incomplete type (and void is an
incomplete type). The code simply won't compile.
Any conforming C or C++ compiler must issue a diagnostic for any
attempt to peform pointer arithmetic on a pointer to an incomplete
type, since it's a constraint violation. At least in C, it's not
actually required to reject the translation unit; it may legally
compile it successfully, and the resulting program has behavior that
is not defined by the standard (though of course it may be defined by
the implementation).

The only case where a C translation unit *must* be rejected is when it
contains a #error directive that survives preprocessing. I'm not sure
what the corresponding rules are for C++.

In particular, gcc (specifically the C compiler that's part of the gcc
suite) allows arithmetic on void* by default. This is a permissible
extension as long as it issues a diagnostic. g++ doesn't support this
particular extension by default; I don't know whether it has an option
to enable it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 7 '08 #34

P: n/a
Davy wrote:
Hi all,

I am writing a function, which return the pointer of the int. But it
seems to be wrong. Any suggestion?

int * get_p_t(int t) {
return &t;
}

int main()
{
printf("v1\n");
int t = 5;
int * p_t[2];

p_t[0] = &t; // right
p_t[1] = get_p_t(t); //wrong

return 0;
}

Best regards,
Davy
change
int * get_p_t(int t) {
to
int * get_p_t(int&t) {
Nov 7 '08 #35

This discussion thread is closed

Replies have been disabled for this discussion.