|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi there,
suppose i have piece of code like main() { int i,j; for(i=0;i<10;i++){ int k = i; printf("%d %p = *%d\n",i,&k,k); } } When i see the address of K its same in all iterations.That means K is only defined once at a time. Is it because each for loop execution is considered as separte block,its allocating in the same address? or is it allocated memory only once? |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
In article <053518bc-6e3c-4bcd-b9e5-504f1707ca7e@f10g2000hsf.googlegroups.com>,
<poornimamprabhu@gmail.com> wrote: >suppose i have piece of code like >main() >{ > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } >} >When i see the address of K its same in all iterations.That means K is >only defined once at a time. >Is it because each for loop execution is considered as separte >block,its allocating in the same address? >or is it allocated memory only once? The answer is compiler dependant. C does not define when or where memory allocation is made for automatic variables: it only defines rules for when storage is meaningfully accessible, and rules about which declaration of a name is the one denoted by a mention of the name. In some compilers the answer would be "neither of the above". For example some compilers allocate automatic variables from a heap, so the fact that the variable showed up with a particular address in each iteration could just reflect the fact that no unreleased heap allocations were made between iterations of the loop. -- "Is there any thing whereof it may be said, See, this is new? It hath been already of old time, which was before us." -- Ecclesiastes |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On Jan 31, 2:25 pm, poornimampra...@gmail.com wrote:
> Hi there, > > suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > > } > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? because each for loop execution is considered as separte block. And the memory address of K should be random. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
poornimamprabhu@gmail.com wrote:
> Hi there, > > suppose i have piece of code like Include stdio.h here. > main() int main(void) is better form. > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); You probably want: printf("%d\t%p = %d\n", i, (void *)&k, k); The 'p' format specifier expects a void * value and the type of the value yielded by the address-of operator is "pointer to T" where T is the type of it's operand. Also the '*' character in your format string specifies that the following formatting operation be of the minimum field width specified by the corresponding argument to '*'. In this case it is the fourth printf() argument and thus, the final 'd' specifier is left without an argument, invoking undefined behaviour. > } > } > > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? This is implementation dependant. You cannot rely on the address of 'k' being the same across iterations. However the compiler is very likely to "optimise" in such cases and create and destroy 'k' only once for the entire duration of the loop. But you cannot rely on such behaviour. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
poornimamprabhu@gmail.com wrote:
> Hi there, > > suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > } > > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. I don't understand what you mean by "once at a time" > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? Who knows? More importantly, who cares? 1) The compiler's optimisation routines could have determined that there was no need for k to be in the nested block and moved it out 2) The management of memory at run time could (very likely would, I suspect) mean that the same address was allocated each time through the loop 3) There may be some other explanation None of this behaviour is guaranteed by the standard, and it is far from certain that it would be the same in another environment. Why are you bothered about how the compiler has organised things? |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Jan 30, 10:25pm, poornimampra...@gmail.com wrote:
> Hi there, > > suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > > } > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? There is also this possibility: the address of k was produced only because you asked for it with the & operator, and the existence of this address doesn't prove that the value of k is actually ever stored there. |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Wed, 30 Jan 2008 22:47:11 -0800, DDD wrote:
> On Jan 31, 2:25 pm, poornimampra...@gmail.com wrote: >> Hi there, >> >> suppose i have piece of code like >> main() >> { >> int i,j; >> for(i=0;i<10;i++){ >> int k = i; >> printf("%d %p = *%d\n",i,&k,k); >> } >> >> } >> >> When i see the address of K its same in all iterations.That means K is >> only defined once at a time. >> Is it because each for loop execution is considered as separte >> block,its allocating in the same address? or is it allocated memory >> only once? > > because each for loop execution is considered as separte block. And the > memory address of K should be random. Why? There's no reason - as far as I can tell from the standard - to expect that it _will_ have a random address, just that it _can_. The optimizer may have found that each iteration does the equivalent of "jump over N bytes, leaving that space to hold k", which is a waste of time in this code - move it out of the loop and the loop will run faster, the code can't tell the difference and the address won't change. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
poornimamprabhu@gmail.com wrote:
> Hi there, > > suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > } > > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. For some compilers like lcc-win this is the case. lcc-win allocates all local variables of the function, no matter what scope, at the start of the function. The stack is not modified within the function. This is done for obvious performance reasons. Imagine that at the end of the block the stack was adjusted, and at the start space for the variable would be created. This would make for at least 2 instructions per block iteration... not a good idea. Of course, the *scope* of the variable is ONLY within the enclosing block. After the block is left, there is no way to access that stack position within C, unless you take the address of the local variable. main() { int i,j, *pint; for(i=0;i<10;i++){ int k = i; printf("%d %p = *%d\n",i,&k,k); pint=&i; } *pint = 789; // Accessing illegal storage } This would work on lcc-win since the storage is still valid. I would not do this since it is absolutely non portable. Other compilers could implement other strategies. For instance main() { int i,j; for(i=0;i<10;i++){ int k = i; printf("%d %p = *%d\n",i,&k,k); } for(i=0;i<10;i++){ int k = i; printf("%d %p = *%d\n",i,&k,k); } } The second "k" could be aliased by the compiler to the first one and stored at the same memory location. > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? For lcc-win it is the second. -- jacob navia jacob at jacob point remcomp point fr logiciels/informatique http://www.cs.virginia.edu/~lcc-win32 |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
jacob navia wrote:
<snip> > main() > { > int i,j, *pint; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > pint=&i; > } > *pint = 789; // Accessing illegal storage > } > > This would work on lcc-win since the storage is still valid. > I would not do this since it is absolutely non portable. > Other compilers could implement other strategies. I hope as a QoI issue lcc-win issues a diagnostic for such uses? <snip> |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
Kaz Kylheku <kkylheku@gmail.com> writes:
> On Jan 30, 10:25pm, poornimampra...@gmail.com wrote: >> int k = i; >> printf("%d %p = *%d\n",i,&k,k); [%p takes a 'void*' and '&k' isn't one] > There is also this possibility: the address of k was produced only > because you asked for it with the & operator, and the existence of > this address doesn't prove that the value of k is actually ever stored > there. In the case that the programmer examines 'k', is the implementation permitted to behave as if 'k' does _not_ contain the value of 'i'? mlp |
|
|
|
#11 |
|
Messages: n/a
Hébergeur: |
jacob navia <jacob@nospam.com> writes:
> main() > { > int i,j, *pint; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > pint=&i; > } > *pint = 789; // Accessing illegal storage What's illegal about it? If the last statement inside the loop body had instead been pint=&k; then you might have a point. mlp |
|
|
|
#12 |
|
Messages: n/a
Hébergeur: |
Mark L Pappin wrote:
> jacob navia <jacob@nospam.com> writes: > >> main() >> { >> int i,j, *pint; >> for(i=0;i<10;i++){ >> int k = i; >> printf("%d %p = *%d\n",i,&k,k); >> pint=&i; >> } >> *pint = 789; // Accessing illegal storage > > What's illegal about it? > > If the last statement inside the loop body had instead been > pint=&k; > then you might have a point. > > mlp Yes, I mistyped the name of the variable Thanks -- jacob navia jacob at jacob point remcomp point fr logiciels/informatique http://www.cs.virginia.edu/~lcc-win32 |
|
|
|
#13 |
|
Messages: n/a
Hébergeur: |
In article <fns04t$ve0$1@aioe.org>, santosh <santosh.k83@gmail.com> wrote:
>poornimamprabhu@gmail.com wrote: >> printf("%d %p = *%d\n",i,&k,k); >You probably want: > printf("%d\t%p = %d\n", i, (void *)&k, k); >Also the '*' character in your format string >specifies that the following formatting operation be of the minimum >field width specified by the corresponding argument to '*'. In this >case it is the fourth printf() argument and thus, the final 'd' >specifier is left without an argument, invoking undefined behaviour. That only applies if the * follows the %. Outside of a % specifier, an * represents the literal character '*'. -- "Beware of bugs in the above code; I have only proved it correct, not tried it." -- Donald Knuth |
|
|
|
#14 |
|
Messages: n/a
Hébergeur: |
poornimamprabhu wrote:
> Hi there, > > suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > } > > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. The compiler *is* allowed to place k in a different place each time, but, why should it? -- Army1987 (Replace "NOSPAM" with "email") |
|
|
|
#15 |
|
Messages: n/a
Hébergeur: |
santosh wrote:
) You probably want: ) ) printf("%d\t%p = %d\n", i, (void *)&k, k); ) ) The 'p' format specifier expects a void * value and the type of the ) value yielded by the address-of operator is "pointer to T" where T is ) the type of it's operand. Aren't casts to and from (void *) automatic ? ) Also the '*' character in your format string ) specifies that the following formatting operation be of the minimum ) field width specified by the corresponding argument to '*'. Only if the * is between the % and the d. ) This is implementation dependant. You cannot rely on the address of 'k' ) being the same across iterations. However the compiler is very likely ) to "optimise" in such cases and create and destroy 'k' only once for ) the entire duration of the loop. But you cannot rely on such behaviour. The optimizer may even decide not to create or destroy k at all, when it realises it's always equal to i, and at the printf call just insert a seemingly valid value for the %p. Have you looked at the assembly output for your loop ? SaSW, Willem -- Disclaimer: I am in no way responsible for any of the statements made in the above text. For all I know I might be drugged or something.. No I'm not paranoid. You all think I'm paranoid, don't you ! #EOT |
|
|
|
#16 |
|
Messages: n/a
Hébergeur: |
In article <slrnfq41su.1kq4.willem@snail.stack.nl>,
Willem <willem@stack.nl> wrote: >santosh wrote: >) You probably want: >) printf("%d\t%p = %d\n", i, (void *)&k, k); >) The 'p' format specifier expects a void * value and the type of the >) value yielded by the address-of operator is "pointer to T" where T is >) the type of it's operand. >Aren't casts to and from (void *) automatic ? No, not when passing a parameter to a function. -- "I will speculate that [...] applications [...] could actually see a performance boost for most users by going dual-core [...] because it is running the adware and spyware that [...] are otherwise slowing down the single CPU that user has today" -- Herb Sutter |
|
|
|
#17 |
|
Messages: n/a
Hébergeur: |
santosh wrote, On 31/01/08 09:49:
> jacob navia wrote: > > <snip> > >> main() >> { >> int i,j, *pint; >> for(i=0;i<10;i++){ >> int k = i; >> printf("%d %p = *%d\n",i,&k,k); >> pint=&i; >> } >> *pint = 789; // Accessing illegal storage >> } >> >> This would work on lcc-win since the storage is still valid. >> I would not do this since it is absolutely non portable. >> Other compilers could implement other strategies. > > I hope as a QoI issue lcc-win issues a diagnostic for such uses? I'm assuming you misread Jacob's code as saying "pint=&k" which is what he intended (as noted in a subsequent post). If so then I would not expect a diagnostic although I would be pleased if the compiler produced one. -- Flash Gordon |
|
|
|
#18 |
|
Messages: n/a
Hébergeur: |
Walter Roberson wrote, On 31/01/08 17:45:
> In article <slrnfq41su.1kq4.willem@snail.stack.nl>, > Willem <willem@stack.nl> wrote: >> santosh wrote: >> ) You probably want: > >> ) printf("%d\t%p = %d\n", i, (void *)&k, k); > >> ) The 'p' format specifier expects a void * value and the type of the >> ) value yielded by the address-of operator is "pointer to T" where T is >> ) the type of it's operand. > >> Aren't casts to and from (void *) automatic ? > > No, not when passing a parameter to a function. You mean not always when passed in all positions to a function. The following fragment is valid assuming stdio.h has been included. void *fred = "fred is at %p\n"; printf(fred,fred); This is valid because the prototype for printf specifies that the first parameters is of type const char *. The following, on the other hand, is invalid char *derf = "derf is at %p\n"; printf(derf,derf); This is invalid because the prototype for printf does not specify the type of the second (or subsequent) parameter, so the rules of C specify that no conversion takes place. Change the %p to a %s and it becomes valid. -- Flash Gordon |
|
|
|
#19 |
|
Messages: n/a
Hébergeur: |
poornimamprabhu@gmail.com writes:
> suppose i have piece of code like > main() > { > int i,j; > for(i=0;i<10;i++){ > int k = i; > printf("%d %p = *%d\n",i,&k,k); > } > } > > > When i see the address of K its same in all iterations.That means K is > only defined once at a time. > Is it because each for loop execution is considered as separte > block,its allocating in the same address? > or is it allocated memory only once? The name "k" refers to a distinct object for each iteration of the loop. Conceptually, that object is created on entry to the block (the "{") and destroyed on exit from the block (the "}"). Though there are going to be 10 logically distinct objects, only one of them will exist at any particular time. Similarly, if this code were inside a function other than main, the variables "i" and "j" would exist only while that function is executing. (The same thing applies to main, but the concept is easier to understand if you consider a more ordinary function.) That's what the C language requires. It doesn't specify exactly what a particular implementation must do to meet this requirement. There are several ways to do this. Many, perhaps most, implementations use a contiguous hardware stack for allocation of local variables. In such an implementation, *either* shared space for all instances of "k" is allocated on entry to the function, *or* space for "k" is allocated and deallocated on each iteration of the loop. In both cases, all instances of "k" are likely to have the same address. This is just a consequence of the most natural way to implement what the language requires; it is not itself required by the language, and you should not depend on it. For example, some implementations might allocate local storage on a "heap", where successive allocations are not necessarily consecutive in memory. In such an implementation, *if* "k" is allocated separately each time the block is executed, then it could easily have a different address on each iteration. In any case, if you stick to what the language guarantees it's not easy even to check whether all 10 "k"s have the same address. As soon as "k" goes out of scope, even looking at its address without dereferencing it invokes undefined behavior. You can, as you did, display the address with printf and "%p", but the resulting text string is implementation-defined, and it's not clear how much information you can *portably* get out of it. The best answer is just not to worry about it. Know that the compiler will do what the standard requires it to do (unless it's buggy, which does happen). If you're curious about how it does this, that's great; curiosity is A Good Thing. But if your program actually depends on the details, either you're doing something wrong or you're doing something subtle and implementation-specific; in the latter rare case, you'd better know exactly what you're doing. (Somebody else in this thread already told you about the need to use (void*)&k rather than just &k with the "%p" format. A couple of other quibbles that aren't relevant to your question: use "int main(void)" rather than "main()", and be sure you have a "#include <stdio.h>" at the top of your program. You might be able to get away with "main()" and without "#include <stdio.h>", but do it right anyway.) -- Keith Thompson (The_Other_Keith) <kst-u@mib.org> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" |
|
|
|
#20 |
|
Messages: n/a
Hébergeur: |
On 31 Jan 2008 23:00:36 +1000, Mark L Pappin <mlp@acm.org> wrote in
comp.lang.c: > Kaz Kylheku <kkylheku@gmail.com> writes: > > > On Jan 30, 10:25pm, poornimampra...@gmail.com wrote: > > >> int k = i; > >> printf("%d %p = *%d\n",i,&k,k); > > [%p takes a 'void*' and '&k' isn't one] > > > There is also this possibility: the address of k was produced only > > because you asked for it with the & operator, and the existence of > > this address doesn't prove that the value of k is actually ever stored > > there. > > In the case that the programmer examines 'k', is the implementation > permitted to behave as if 'k' does _not_ contain the value of 'i'? No, it can't behave that way. It must behave "as if" 'k' exists and is written to and read from as specified by the source code, in any way that effects the output of the program. But a sufficiently clever compiler could deduce: 1. The address of 'i' is not taken. 2. The address and value of 'k' are both taken in one and only one place. 3. The value of 'k' will not be changed by the printf() function, even though that function is passed a pointer to 'k'. It can "know" this because printf() is a standard library function and such behavior is mandated for it. 4. At the one and only one place where and address and value of 'k' are taken, the value of 'k' is always equal to 'i'. ....and that sufficiently clever compiler could then pass the address of 'i' as the second variable argument to printf(), and the value of 'i' as the third. 'k' does not actually need to exist at all. No output produced by this program could tell. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html |
|
![]() |
| Outils de la discussion | |
|
|