|
|
|
#26 |
|
Messages: n/a
Hébergeur: |
On Wed, 5 Nov 2008 22:30:03 -0800 (PST), baichuan0798@163.com wrote:
>On 11??5??, ????3??06??, Davy <zhushe...@gmail.com> wrote: >> On Nov 5, 2:49 pm, Ian Collins <ian-n...@hotmail.com> wrote: >> >> > 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 |
|
|
|
#27 |
|
Messages: n/a
Hébergeur: |
On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.com> wrote:
> 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:james.kanze@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 |
|
|
|
#28 |
|
Messages: n/a
Hébergeur: |
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"? |
|
|
|
#29 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> writes:
> On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.com> wrote: >> 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. |
|
|
|
#30 |
|
Messages: n/a
Hébergeur: |
On Nov 6, 3:44pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> James Kanze <james.ka...@gmail.com> writes: > > On Nov 6, 7:39 am, Barry Schwarz <schwa...@dqel.com> wrote: > >> 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:james.kanze@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 |
|
|
|
#31 |
|
Messages: n/a
Hébergeur: |
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. |
|
|
|
#32 |
|
Messages: n/a
Hébergeur: |
James Kanze <james.kanze@gmail.com> writes:
[...] > 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) kst-u@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" |
|
|
|
#33 |
|
Messages: n/a
Hébergeur: |
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) { |
|
|
|
#34 |
|
Messages: n/a
Hébergeur: |
Michael <michael@michaeldadmum.no-ip.org> writes:
[...] > 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) kst-u@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" |
|
![]() |
| Outils de la discussion | |
|
|