By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,462 Members | 1,455 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,462 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+
49 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
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 #6

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 #7

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 #8

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 #9

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 #10

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 #11

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 #12

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 #13

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 #14

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 #15

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 #16

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 #17

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 #18

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 #19

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 #20

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 #21

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 #22

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 #23

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 #24

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 #25

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 #26

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 #27

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 #28

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 #29

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 #30

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 #31

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 #32

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 #33

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 #34

P: n/a
Harald van =?UTF-8?b?RMSzaw==?= <tr*****@gmail.comwrites:
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.
Using a trap representation in a value context is undefined behavior
(as I recently explained in another posting, agreeing with the
comments of James Kuyper). The reason is, the semantics are defined
in terms of value, but a trap representation doesn't represent any
value; since there is no definition for how expressions behave when
there is no value, the result is undefined behavior.

An argument could be made that a (void) expression never uses its
value, so perhaps writing 'foo(something);' would be allowed.
But any other attempt to use trap representation's value, including
comparison, would require that what its value is be defined,
and it isn't; ergo, UB.
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.
Section 6.2.6, which clearly is the starting point here, is titled
"Representation of types", not "Representation of objects". The
first 1.5 sentences of 6.2.6.1 p 5 clarify the distinction

Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation

The word "value" is being used in two distinct senses: one, a
point in the value space for the type in question; and two, a
the bits of a stored representation (as might be seen as a value
of, eg., (unsigned char [sizeof (T)]). The result of the function
is held in memory as a "value" in the second sense; any attempt
to use it needs the "value" in the first sense.

It's unfortunate that the Standard uses the term "value" in both of
these senses (and don't even get me started about calling invalid
pointers "trap representations"), but the meaning is clear. It is
a _representation_ value (or (unsigned char [sizeof(T)]) value if
you prefer) that can be a trap representation; a type's value
is defined only if the representation value isn't a trap
representation.
Nov 10 '08 #35

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?
It depends on how you read 6.3.2.2 p 1:

The (nonexistent) value of a void expression (an expression that
has type void) shall not be used in any way, and implicit or
explicit conversions (except to void) shall not be applied to such
an expression. If an expression of any other type is evaluated as
a void expression, its value or designator is discarded. (A void
expression is evaluated for its side effects.)

If you think this conversion needs a value of the (unconverted)
type of the expression, then 'foo(0);' is undefined behavior;
if you think the conversion to (void) discards the function
result without needing a value of type (int *), then it's okay.
Nov 10 '08 #36

P: n/a
Keith Thompson <ks***@mib.orgwrites:
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.
Anything an implementation does beyond the semantics of the abstract
machine aren't relevant; in particular the sentence

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.

in 6.2.6.1 p 5 doesn't apply, since stores to an address register
don't correspond to any abstract semantics side effect. Comments
about address registers (or registers in general for that matter)
might tell us /why/ something is undefined behavior, but don't
tell us /whether/ something is undefined behavior.

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.
As I just explained responding to Harald's posting, the term "value"
is used in the standard to mean both (a) a point in the space of the
type in question, and (b) a point in the representation space (which
is isomorphic to values in (unsigned char [sizeof(T)])) of memory used
to hold variables and expression results. Obviously I think that
ambiguity should be clarified, but the meaning seems clear.

Nov 10 '08 #37

P: n/a
On Mon, 10 Nov 2008 09:36:49 -0800, Tim Rentsch wrote:
Using a trap representation in a value context is undefined behavior (as
I recently explained in another posting, agreeing with the comments of
James Kuyper). The reason is, the semantics are defined in terms of
value, but a trap representation doesn't represent any value; since
there is no definition for how expressions behave when there is no
value, the result is undefined behavior.
Either the trap representation is a value, or the trap representation is
not a value. If it is, for pointer types, 6.5.9p6 defines the behaviour of
comparisons. If it is not, the value simply cannot be a trap
representation.
An argument could be made that a (void) expression never uses its value,
so perhaps writing 'foo(something);' would be allowed. But any other
attempt to use trap representation's value, including comparison, would
require that what its value is be defined, and it isn't; ergo, UB.
See above. Adding 0 to a pointer trap representation is undefined by
omission. Comparing 0 to a pointer trap representation is not, because a
pointer trap representation is by definition a pointer non-value, and
therefore isn't a null pointer, a pointer to an object, or a pointer to
one past the end of an array.
>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.

Section 6.2.6, which clearly is the starting point here, is titled
"Representation of types", not "Representation of objects".
They're the same thing. The representation is how a type is stored in an
object. How a type is stored in a register or any other location is
irrelevant and not addressed by 6.2.6 at all. "Object representation" is
defined in 6.2.6.1p4 and "representation" is clearly used as a shortened
form to mean exactly the same thing in at least 6.2.6.1p8, 6.2.6.2p2, and
6.2.6.2p5.
The first
1.5 sentences of 6.2.6.1 p 5 clarify the distinction

Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation

The word "value" is being used in two distinct senses: one, a point in
the value space for the type in question; and two, a the bits of a
stored representation (as might be seen as a value of, eg., (unsigned
char [sizeof (T)]).
No, that second sense is what's called the object representation, see
6.2.6.1p4. If that's a value at all, it's a series of values of type
unsigned char, not a value of (for example) type int *.
The result of the function is held in memory as a "value" in the second
sense; any attempt to use it needs the "value" in the first sense.
How the result of the function is held in memory is not addressed at all.
It's unfortunate that the Standard uses the term "value" in both of
these senses (and don't even get me started about calling invalid
pointers "trap representations"), but the meaning is clear. It is a
_representation_ value (or (unsigned char [sizeof(T)]) value if you
prefer) that can be a trap representation; a type's value is defined
only if the representation value isn't a trap representation.
I think you're reading more into "value" than what the standard actually
says.
Nov 10 '08 #38

P: n/a
James Kuyper <ja*********@verizon.netwrites:
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.
Not quite - "by an lvalue expression that does not have character
type" (6.2.6.1 p 5). That's a little different than "any method other
than use of an lvalue of character type". In the second case, the
/absence/ of an lvalue of character type implies undefined behavior;
but in the first case, the /presence/ of an lvalue is required for
(explicit) undefined behavior, and there is UB only if it does not
have character type.

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.
I think the fundamental problem is using the term "value" in two
distinct senses, which IMO the standard pretty clearly does. If there
were distinct terms for "a value of type T" and "a representation
value", most of the confusion would go away.

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"?
The term "trap representation", as the standard defines it, doesn't
carry over very well into pointer types. At any given point in time,
the set of representation values for a pointer type may be divided
into three sets: one, those representation values that /never/
correspond to actual pointer values; two, those representation values
that /might/ correspond to an actual pointer value but don't at the
moment (an "invalid pointer value"); and three, those representation
values that /do/ correspond to an actual pointer value at this moment
(a "valid pointer value").

Of course, these terms (representation value, invalid pointer value,
valid pointer value) are my suggestions for terms rather than terms
currently used in the standard. I offer them for consideration for
a future revision, or at least to start a discussion about other
suitable terminology (and so crossposting to comp.std.c).
Nov 10 '08 #39

P: n/a
Harald van =?UTF-8?b?RMSzaw==?= <tr*****@gmail.comwrites:
On Mon, 10 Nov 2008 09:36:49 -0800, Tim Rentsch wrote:
Using a trap representation in a value context is undefined behavior (as
I recently explained in another posting, agreeing with the comments of
James Kuyper). The reason is, the semantics are defined in terms of
value, but a trap representation doesn't represent any value; since
there is no definition for how expressions behave when there is no
value, the result is undefined behavior.

Either the trap representation is a value, or the trap representation is
not a value. If it is, for pointer types, 6.5.9p6 defines the behaviour of
comparisons. If it is not, the value simply cannot be a trap
representation.
This reasoning implicitly assumes that the term "value" has only one
meaning. The standard uses "value" to mean different things in
different places.
An argument could be made that a (void) expression never uses its value,
so perhaps writing 'foo(something);' would be allowed. But any other
attempt to use trap representation's value, including comparison, would
require that what its value is be defined, and it isn't; ergo, UB.

See above. Adding 0 to a pointer trap representation is undefined by
omission. Comparing 0 to a pointer trap representation is not, because a
pointer trap representation is by definition a pointer non-value, and
therefore isn't a null pointer, a pointer to an object, or a pointer to
one past the end of an array.
Evaluating the operand expression 'f(0)' does not produce a "pointer";
it produces a value, an object or function designator, or nothing at
all (6.5p1). We can be more specific: by 6.5.2.2p5, if 'f(0)' is
a legal call and does not return (void), it produces a value. If
the result of 'f(0)' is a trap representation and so the value is undefined,
the result is undefined behavior.

More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.

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.
Section 6.2.6, which clearly is the starting point here, is titled
"Representation of types", not "Representation of objects".

They're the same thing. The representation is how a type is stored in an
object. How a type is stored in a register or any other location is
irrelevant and not addressed by 6.2.6 at all. "Object representation" is
defined in 6.2.6.1p4 and "representation" is clearly used as a shortened
form to mean exactly the same thing in at least 6.2.6.1p8, 6.2.6.2p2, and
6.2.6.2p5.
That's funny. In your earlier posting you cite a section that clearly
shows that the notion of representation applies outside of any stored
object, and then claim that representation matters only inside an
object. I guess I should say thank you for making my point for me. :)

The first
1.5 sentences of 6.2.6.1 p 5 clarify the distinction

Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation

The word "value" is being used in two distinct senses: one, a point in
the value space for the type in question; and two, a the bits of a
stored representation (as might be seen as a value of, eg., (unsigned
char [sizeof (T)]).

No, that second sense is what's called the object representation, see
6.2.6.1p4. If that's a value at all, it's a series of values of type
unsigned char, not a value of (for example) type int *.
Do you see that the section I cited uses the term "value" more than
once? Do you see that the meanings in the two cases are not the same?
Are you claiming the Standard is wrong in what terms it uses to
define the language -- that people should use your terminology rather
than the words actually used in the Standard?

The result of the function is held in memory as a "value" in the second
sense; any attempt to use it needs the "value" in the first sense.

How the result of the function is held in memory is not addressed at all.
It's unfortunate that the Standard uses the term "value" in both of
these senses (and don't even get me started about calling invalid
pointers "trap representations"), but the meaning is clear. It is a
_representation_ value (or (unsigned char [sizeof(T)]) value if you
prefer) that can be a trap representation; a type's value is defined
only if the representation value isn't a trap representation.

I think you're reading more into "value" than what the standard actually
says.
I notice the last statement is simply a deflecting comment and ad hominem
remark (and also made without any supporting evidence).

The term "value" is used extensively in the Standard. By my counting,
in just sections 1-6, it appears nearly 400 times in more than 200
separate paragraphs. In most of those places it's used in the sense
of "value of a particular type" (or numeric/mathematical value, which
is almost the same thing). In many places it might mean the value of
a particular type or the representation of some value of a particular
type, and it's somewhat ambiguous which. In some places it's used
in the sense of "contents of an object", as for example 6.5.2.4p5,
talking about ++/-- operators:

After the result is obtained, the value of the operand is incremented.

Of course, that's absurd, values can't incremented; what's meant is
that the contents of the object holding the value is incremented.
But the Standard does use the term "value".

In a fair number of places "value" is used to mean representation
value: 6.2.4p5, 6.2.6.1p5, 6.2.6.2p3, 6.5.3.2p4, 6.7.8p9, 6.8.4.2p7
are representative examples.

I think it should be clear to anyone who takes the time to look that
"value" is used in the Standard with several different meanings.

Nov 17 '08 #40

P: n/a
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
[...]
Evaluating the operand expression 'f(0)' does not produce a "pointer";
it produces a value, an object or function designator, or nothing at
all (6.5p1). We can be more specific: by 6.5.2.2p5, if 'f(0)' is
a legal call and does not return (void), it produces a value. If
the result of 'f(0)' is a trap representation and so the value is undefined,
the result is undefined behavior.

More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.
[...]

The standard sometimes uses the term "pointer" in a different way than
you do. A value of pointer type is sometimes referred to as a "pointer".

See for example, C99 7.20.3.3p3:

The malloc function returns either a null pointer or a pointer to
the allocated space.

Personally, I'd be happier if the unqualified term "pointer" referred
only to an object of pointer type, with values of pointer type being
called "addresses", but that's not how the standard uses the word.

--
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 18 '08 #41

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
[...]
Evaluating the operand expression 'f(0)' does not produce a "pointer";
it produces a value, an object or function designator, or nothing at
all (6.5p1). We can be more specific: by 6.5.2.2p5, if 'f(0)' is
a legal call and does not return (void), it produces a value. If
the result of 'f(0)' is a trap representation and so the value is undefined,
the result is undefined behavior.

More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.
[...]

The standard sometimes uses the term "pointer" in a different way than
you do. A value of pointer type is sometimes referred to as a "pointer".

See for example, C99 7.20.3.3p3:

The malloc function returns either a null pointer or a pointer to
the allocated space.

Personally, I'd be happier if the unqualified term "pointer" referred
only to an object of pointer type, with values of pointer type being
called "addresses", but that's not how the standard uses the word.
Right, the word pointer in the standard sometimes means a value of
pointer type. That's actually what I was trying to get at, although
evidently I didn't express that very clearly. The key thing is that a
/value/ is required, so if what's supplied isn't a value (of type T*)
then the result of doing == is undefined behavior.
Nov 18 '08 #42

P: n/a
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
Keith Thompson <ks***@mib.orgwrites:
>Tim Rentsch <tx*@alumnus.caltech.eduwrites:
[...]
Evaluating the operand expression 'f(0)' does not produce a
"pointer"; it produces a value, an object or function designator,
or nothing at all (6.5p1). We can be more specific: by
6.5.2.2p5, if 'f(0)' is a legal call and does not return (void),
it produces a value. If the result of 'f(0)' is a trap
representation and so the value is undefined, the result is
undefined behavior.

More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.
[...]

The standard sometimes uses the term "pointer" in a different way than
you do. A value of pointer type is sometimes referred to as a "pointer".
[snip]
>
Right, the word pointer in the standard sometimes means a value of
pointer type. That's actually what I was trying to get at, although
evidently I didn't express that very clearly. The key thing is that a
/value/ is required, so if what's supplied isn't a value (of type T*)
then the result of doing == is undefined behavior.
Ah, I see what you mean. The problem was that I only saw 'f(0)';
the definition of f:

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

had been lost in snippage a couple of articles further upthread. With
that context, what you wrote makes sense.

--
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 18 '08 #43

P: n/a
On Mon, 17 Nov 2008 15:45:50 -0800, Tim Rentsch wrote:
This reasoning implicitly assumes that the term "value" has only one
meaning. The standard uses "value" to mean different things in
different places.
No, it doesn't -- and if it did, it would be wrong. The definition of
value is given in the standard (3.17), so when the standard refers to a
value, the meaning is always as defined. (Note that "indeterminate value"
has a definition of its own, and should not be read in its ordinary
English meaning of a value(3.17) that is indeterminate.)
Evaluating the operand expression 'f(0)' does not produce a "pointer";
it produces a value, an object or function designator, or nothing at all
(6.5p1).
It produces a value of pointer type. I called that a pointer; if you don't
want to, I have no problems with that.
We can be more specific: by 6.5.2.2p5, if 'f(0)' is a legal call and
does not return (void), it produces a value. If the result of 'f(0)' is
a trap representation and so the value is undefined, the result is
undefined behavior.
Given that f(0) produces a value, it is not a trap representation as the
function result. (However, this does not mean you can store it in an
object. The value is indeterminate, and storing it may try to store a trap
representation.)
More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.
As above.
That's funny. In your earlier posting you cite a section that clearly
shows that the notion of representation applies outside of any stored
object, and then claim that representation matters only inside an
object.
It's also funny how you conveniently ignore that I added that I did not
see how that section made sense, given the definitions used by the
standard, and otherwise ignored it because it was not important for the
rest of my message at the time.
Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation

Do you see that the section I cited uses the term "value" more than
once? Do you see that the meanings in the two cases are not the same?
I do now.
Are you claiming the Standard is wrong in what terms it uses to define
the language
I wasn't, but am now.
-- that people should use your terminology rather than the words
actually used in the Standard?
No. The standard should use its own definitions. "value" has a specific
definition. It's not something I made up, it's in the standard and you can
look it up yourself.
>I think you're reading more into "value" than what the standard
actually says.

I notice the last statement is simply a deflecting comment and ad
hominem remark (and also made without any supporting evidence).
Excuse me? What I said can be rephrased as roughly "I think the standard
doesn't actually say what you claim it says." and the rest of my message
already explained why I thought so.
The term "value" is used extensively in the Standard. [...] In some
places it's used in
the sense of "contents of an object", as for example 6.5.2.4p5, talking
about ++/-- operators:

After the result is obtained, the value of the operand is
incremented.

Of course, that's absurd, values can't incremented; what's meant is
that the contents of the object holding the value is incremented. But
the Standard does use the term "value".
Interesting. "One is added to the value of the operand" makes perfect
sense with 3.17's definition of value: it means (operand)+1 is evaluated.
What the standard fails to mention is that the result of the addition is
stored back in ++'s operand.
In a fair number of places "value" is used to mean representation value:
6.2.4p5,
Indeterminate value -- see above.
6.2.6.1p5,
Agreed.
6.2.6.2p3,
Not at all. The bitwise operators aren't defined in terms of
representation.
6.5.3.2p4,
This makes more sense with 3.17's definition than with yours. An invalid
value, when applied to the * operator, is a value such as a null pointer
or a pointer past the end of an array. If the operand is an lvalue holding
a trap representation, the behaviour is already undefined before the *
operator is evaluated.
6.7.8p9,
Indeterminate value -- see above.
6.8.4.2p7
Indeterminate value -- see above.
are representative examples.
I think it should be clear to anyone who takes the time to look that
"value" is used in the Standard with several different meanings.
I have taken the time to look. I don't agree with your main conclusion.
Nov 18 '08 #44

P: n/a
Harald van Dijk <tr*****@gmail.comwrites:
On Mon, 17 Nov 2008 15:45:50 -0800, Tim Rentsch wrote:
>This reasoning implicitly assumes that the term "value" has only one
meaning. The standard uses "value" to mean different things in
different places.

No, it doesn't -- and if it did, it would be wrong. The definition of
value is given in the standard (3.17), so when the standard refers to a
value, the meaning is always as defined. (Note that "indeterminate value"
has a definition of its own, and should not be read in its ordinary
English meaning of a value(3.17) that is indeterminate.)
[...]

In my opinion, the standard's definition of "value" is incomplete, and
therefore flawed. The definition is:

precise meaning of the contents of an object when interpreted as
having a specific type

This seems to exclude the result of an expression, which is
"obviously" a value as well. Or is it the intent that the result of
an expression doesn't become a "value" until it's stored in an object?

--
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 18 '08 #45

P: n/a
On Tue, 18 Nov 2008 12:06:17 -0800, Keith Thompson wrote:
In my opinion, the standard's definition of "value" is incomplete, and
therefore flawed. The definition is:

precise meaning of the contents of an object when interpreted as
having a specific type

This seems to exclude the result of an expression, which is "obviously"
a value as well.
It seems that way to me as well. I might say the /meaning/ of 5 when read
from an object is identical to the meaning of 5 as an integer literal, so
if the first matches the definition of value, and the second is the same
as the first, the second is a value as well. That is a big stretch, and
surely not the intended reading.
Or is it the intent that the result of an expression doesn't become a
"value" until it's stored in an object?
If that is the intent (which I doubt), then a whole lot of the uses of the
word "value" in the standard are wrong.
Nov 18 '08 #46

P: n/a
Harald van =?UTF-8?b?RMSzaw==?= <tr*****@gmail.comwrites:
On Mon, 17 Nov 2008 15:45:50 -0800, Tim Rentsch wrote:
This reasoning implicitly assumes that the term "value" has only one
meaning. The standard uses "value" to mean different things in
different places.

No, it doesn't -- and if it did, it would be wrong. The definition of
value is given in the standard (3.17), so when the standard refers to a
value, the meaning is always as defined. (Note that "indeterminate value"
has a definition of its own, and should not be read in its ordinary
English meaning of a value(3.17) that is indeterminate.)
Okay, let's go with your assumption and see where that gets us.

Evaluating the operand expression 'f(0)' does not produce a "pointer";
it produces a value, an object or function designator, or nothing at all
(6.5p1).

It produces a value of pointer type. I called that a pointer; if you don't
want to, I have no problems with that.
If the pointer points to an object that is past the end of its lifetime,
then it may be a trap representation, which is not a value of pointer
type. It can't be both a value of pointer type and /not/ a value of
pointer type.

By the way, according to 3.17, a "value" is the meaning of the
contents of an object. Using this definition, no expression can
produce values, since meanings cannot be stored in computers.

We can be more specific: by 6.5.2.2p5, if 'f(0)' is a legal call and
does not return (void), it produces a value. If the result of 'f(0)' is
a trap representation and so the value is undefined, the result is
undefined behavior.

Given that f(0) produces a value, it is not a trap representation as the
function result. (However, this does not mean you can store it in an
object. The value is indeterminate, and storing it may try to store a trap
representation.)
Your reasoning step is wrong. Expressions produce values only when
they work; the result not being a trap representation is a
/requirement/ for an expression to produce a value, not a consequence.
This possibility is identified specifically in 6.5 p5:

If an exceptional condition occurs during the evaluation of an
expression (that is, if the result is not mathematically defined
or not in the range of representable values for its type), the
behavior is undefined.

The result of 'f(0)' is not in the range of representable values for
its type, since the object previously pointed at is past the end
of its lifetime.

More generally, there is no way to supply an operand to == that is a
"pointer", because evaluating any operand expression always produces a
value, an object or function designator, or nothing at all.

As above.
Again, if the result of an expression is not in the range of
representable values for its type, no value is produced.

That's funny. In your earlier posting you cite a section that clearly
shows that the notion of representation applies outside of any stored
object, and then claim that representation matters only inside an
object.

It's also funny how you conveniently ignore that I added that I did not
see how that section made sense, given the definitions used by the
standard, and otherwise ignored it because it was not important for the
rest of my message at the time.
Hmmmm. You point out an inconsistency, say explicitly that it doesn't
make sense, and then ignore it since it didn't support your argument?
You're right, I shouldn't have ignored you saying it didn't make
sense -- I should have pointed it out! I must be slipping. :)

Somewhat more seriously, it doesn't make sense only because of the
faulty assumption that the word "value" is used with only one meaning.
Occam's Razor leads to a more satisfactory explanation - the
simpler assumption is that the writing isn't careful to use
"value" with only one meaning.

Certain object representations need not represent a value of the
object type. If the stored value of an object has such a
representation
Do you see that the section I cited uses the term "value" more than
once? Do you see that the meanings in the two cases are not the same?

I do now.
Are you claiming the Standard is wrong in what terms it uses to define
the language

I wasn't, but am now.
-- that people should use your terminology rather than the words
actually used in the Standard?

No. The standard should use its own definitions. "value" has a specific
definition. It's not something I made up, it's in the standard and you can
look it up yourself.
It should use its own definition... but it doesn't (at least in some
places)? You agree that it's used with more than one meaning -- so
you're retracting the claim that the term "value" is used with only
one meaning?

I think you're reading more into "value" than what the standard
actually says.
I notice the last statement is simply a deflecting comment and ad
hominem remark (and also made without any supporting evidence).

Excuse me? What I said can be rephrased as roughly "I think the standard
doesn't actually say what you claim it says." and the rest of my message
already explained why I thought so.
Perhaps being more careful with what wording is used to express your
thoughts will lead to better communication.

That notwithstanding, neither phrasing adds any useful information
towards resolving the issue; both are deflecting comments.

The term "value" is used extensively in the Standard. [...] In some
places it's used in
the sense of "contents of an object", as for example 6.5.2.4p5, talking
about ++/-- operators:

After the result is obtained, the value of the operand is
incremented.

Of course, that's absurd, values can't incremented; what's meant is
that the contents of the object holding the value is incremented. But
the Standard does use the term "value".

Interesting. "One is added to the value of the operand" makes perfect
sense with 3.17's definition of value: it means (operand)+1 is evaluated.
What the standard fails to mention is that the result of the addition is
stored back in ++'s operand.
Yes, "One is added to the value of the operand" would fit better, but
that's not what the Standard says; what it does say makes sense only
if the term "value" has a different meaning than the one in 3.17.

In a fair number of places "value" is used to mean representation value:
6.2.4p5,

Indeterminate value -- see above.
I think you may have missed the point here. What's said is "The
initial value of the object is indeterminate." What's meant is "The
initial contents of the object is an indeterminate value." It doesn't
make sense to put "indeterminate value" in place of "value" in the
original -- "The initial indeterminate value of the object is
indeterminate" is just silly. It's true that the word "value" is
meant to be coupled with the word "indeterminate" here, but it also
serves another purpose, identifying the contents of an object.
There's a similar example in 6.2.6.1p6, "The value of a structure or
union object is never a trap representation". Both of these use
"value" to mean "representation value" (or perhaps "contents",
which is basically the same thing if we have an object of a known
type).

6.2.6.1p5,

Agreed.
6.2.6.2p3,

Not at all. The bitwise operators aren't defined in terms of
representation.
Anything that talks about negative zeros is talking about representation,
because negative zero is defined as being a particular representation -
6.2.6.2p2 says:

In the case of sign and magnitude and ones' complement, if this
representation is a normal value it is called a negative zero.

The representation is what's being identified as a negative zero.

6.5.3.2p4,

This makes more sense with 3.17's definition than with yours. An invalid
value, when applied to the * operator, is a value such as a null pointer
or a pointer past the end of an array. If the operand is an lvalue holding
a trap representation, the behaviour is already undefined before the *
operator is evaluated.
At some level the phrase "invalid value" must be talking about
representation, not meaning; a trap representation doesn't
mean anything viewed as a value of its type -- it's meaningless
when considered as that type. The definition in 3.17 defines
"value" as the meaning of the contents of an object; it's
the contents that are invalid, in other words meaningless.

6.7.8p9,

Indeterminate value -- see above.
The language is sloppy because "indeterminate" is used as an adjective
rather than as part of a compound noun, but if that's taken into
account I agree that the contents of the object are meant to
hold an indeterminate value.

6.8.4.2p7

Indeterminate value -- see above.
Again the language is sloppy and that threw me off -- of course what
was meant is printf will access an object whose contents are an
indeterminate value.

are representative examples.
I think it should be clear to anyone who takes the time to look that
"value" is used in the Standard with several different meanings.

I have taken the time to look. I don't agree with your main conclusion.
It's hard to see how you can say that, since you stated earlier
that you saw two uses of "value" that had different meanings.
Nov 20 '08 #47

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Harald van Dijk <tr*****@gmail.comwrites:
On Mon, 17 Nov 2008 15:45:50 -0800, Tim Rentsch wrote:
This reasoning implicitly assumes that the term "value" has only one
meaning. The standard uses "value" to mean different things in
different places.
No, it doesn't -- and if it did, it would be wrong. The definition of
value is given in the standard (3.17), so when the standard refers to a
value, the meaning is always as defined. (Note that "indeterminate value"
has a definition of its own, and should not be read in its ordinary
English meaning of a value(3.17) that is indeterminate.)
[...]

In my opinion, the standard's definition of "value" is incomplete, and
therefore flawed. The definition is:

precise meaning of the contents of an object when interpreted as
having a specific type

This seems to exclude the result of an expression, which is
"obviously" a value as well.
It's explicitly true that expressions can produce a value -- for
example, 5.1.2.3 p 3.
Or is it the intent that the result of
an expression doesn't become a "value" until it's stored in an object?
No, as implied by the sentence in 6.3.2.2p1: "If an expression of any
other type is evaluated as a void expression, its value or designator
is discarded." Any expression not of type (void) and not a designator
(and that doesn't cause UB) produces a value; storage not required.
Nov 20 '08 #48

P: n/a
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
Keith Thompson <ks***@mib.orgwrites:
[...]
>In my opinion, the standard's definition of "value" is incomplete, and
therefore flawed. The definition is:

precise meaning of the contents of an object when interpreted as
having a specific type

This seems to exclude the result of an expression, which is
"obviously" a value as well.

It's explicitly true that expressions can produce a value -- for
example, 5.1.2.3 p 3.
[...]

Then it's the definition of "value" that needs fixing. It's not a
critical problem, since "everyone knows" what a value is, but it would
be nice not to have to ignore what the standard says to understand
what it means. (The definitions of "expression" and "lvalue" are also
problematic.)

--
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 20 '08 #49

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Tim Rentsch <tx*@alumnus.caltech.eduwrites:
Keith Thompson <ks***@mib.orgwrites:
[...]
In my opinion, the standard's definition of "value" is incomplete, and
therefore flawed. The definition is:

precise meaning of the contents of an object when interpreted as
having a specific type

This seems to exclude the result of an expression, which is
"obviously" a value as well.
It's explicitly true that expressions can produce a value -- for
example, 5.1.2.3 p 3.
[...]

Then it's the definition of "value" that needs fixing.
Not just the definition, but also some of the uses, since "value" is
used with different meanings in different places in the standard,
as I have explained in other postings.

It's not a
critical problem, since "everyone knows" what a value is, but it would
be nice not to have to ignore what the standard says to understand
what it means. (The definitions of "expression" and "lvalue" are also
problematic.)
I think the case of "value" is somewhat more serious, because it
gives rise to truly different interpretations as to what the
standard requires (witness this thread). Beyond that, however,
I completely agree.
Nov 20 '08 #50

This discussion thread is closed

Replies have been disabled for this discussion.