Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #58560 > unrolled thread
| Started by | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| First post | 2015-03-21 00:52 -0700 |
| Last post | 2015-03-26 23:38 -0700 |
| Articles | 20 on this page of 29 — 12 participants |
Back to article view | Back to comp.lang.c
Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-21 00:52 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Richard Heathfield <rjh@cpax.org.uk> - 2015-03-21 08:28 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 20:57 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-21 01:29 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 21:01 -0700
Lexical Variables In C Loops (As Compared To Perl Loops) asetofsymbols@gmail.com - 2015-03-21 01:40 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) jt@toerring.de (Jens Thoms Toerring) - 2015-03-21 08:43 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 20:58 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Richard Heathfield <rjh@cpax.org.uk> - 2015-03-27 06:12 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-26 23:32 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Bartc <bc@freeuk.com> - 2015-03-21 10:54 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-21 13:54 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 21:24 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-03-27 20:35 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Bartc <bc@freeuk.com> - 2015-03-27 21:24 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-03-28 00:03 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Bartc <bc@freeuk.com> - 2015-03-28 10:00 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Stephen Sprunk <stephen@sprunk.org> - 2015-03-28 18:14 -0500
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Kaz Kylheku <kaz@kylheku.com> - 2015-03-21 14:39 +0000
Re: Lexical Variables In C Loops (As Compared To Perl Loops) fir <profesor.fir@gmail.com> - 2015-03-21 09:40 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) James Kuyper <jameskuyper@verizon.net> - 2015-03-21 12:43 -0400
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Philip Lantz <prl@canterey.us> - 2015-03-21 13:01 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) James Kuyper <jameskuyper@verizon.net> - 2015-03-22 18:47 -0400
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-22 16:39 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) James Kuyper <jameskuyper@verizon.net> - 2015-03-22 20:08 -0400
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 22:36 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-26 23:40 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Robbie Hatley <see.my.sig@for.my.address> - 2015-03-26 22:26 -0700
Re: Lexical Variables In C Loops (As Compared To Perl Loops) Keith Thompson <kst-u@mib.org> - 2015-03-26 23:38 -0700
Page 1 of 2 [1] 2 Next page →
| From | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| Date | 2015-03-21 00:52 -0700 |
| Subject | Lexical Variables In C Loops (As Compared To Perl Loops) |
| Message-ID | <ZK2dnYy7U9u2vpDInZ2dnUVZ57ydnZ2d@giganews.com> |
I was wondering if a variable declared inside a for loop in
a C program is defined (memory address allocated) just once,
or if (as in Perl) a fresh (unique) memory address is used
for each iteration. So I wrote this program to find out:
/* lexical-var-test.c */
#include <stdio.h>
int * array[12];
int main(int argc, char *argv[])
{
int i = 0;
for ( i = 1 ; i <= 10 ; ++i ) {
int var = i;
array[i] = &var;
printf("Addr = %p Value = %d\n", (void*)array[i], *array[i]);
}
return 0;
}
And the results of running it are:
Addr = 0x23cb0c Value = 1
Addr = 0x23cb0c Value = 2
Addr = 0x23cb0c Value = 3
Addr = 0x23cb0c Value = 4
Addr = 0x23cb0c Value = 5
Addr = 0x23cb0c Value = 6
Addr = 0x23cb0c Value = 7
Addr = 0x23cb0c Value = 8
Addr = 0x23cb0c Value = 9
Addr = 0x23cb0c Value = 10
So while the value changes, the address stays the same, meaning that
the variable "var" is declared & defined & allocated ONLY ON FIRST
ITERATION; after that, only the value changes.
***** QUESTION: *****
Is this behavior mandated by the C standard? If so, where? I've been
looking, but can't find where it discusses this.
For comparison, Perl handles variables VERY differently. Scope, duration,
definitions, etc. Check out THIS program:
use v5.014.004;
use strict;
use warnings;
our @array;
for (1..10) {
my $var = $_;
$array[$_] = \$var;
}
for (1..10) {
say("Addr = $array[$_] Value = ${$array[$_]}");
}
What that prints is THIS:
Addr = SCALAR(0x6000aa3c8) Value = 1
Addr = SCALAR(0x60002c198) Value = 2
Addr = SCALAR(0x600070290) Value = 3
Addr = SCALAR(0x6000702a8) Value = 4
Addr = SCALAR(0x600070368) Value = 5
Addr = SCALAR(0x6000703f8) Value = 6
Addr = SCALAR(0x600078570) Value = 7
Addr = SCALAR(0x600078678) Value = 8
Addr = SCALAR(0x600078768) Value = 9
Addr = SCALAR(0x600078750) Value = 10
Which shows that in Perl, a variable declared in a for loop
is re-declared & re-defined & re-allocated ON EVERY SINGLE
ITERATION. Very, very different from C. Not better or worse,
just very different. Something to keep in mind for programmers
(such as myself) who program in both languages.
--
Cheers,
Robbie Hatley
Midway City, CA, USA
perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"'
http://www.well.com/user/lonewolf/
https://www.facebook.com/robbie.hatley
[toc] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-03-21 08:28 +0000 |
| Message-ID | <meja1v$1tn$1@dont-email.me> |
| In reply to | #58560 |
On 21/03/15 07:52, Robbie Hatley wrote: > > I was wondering if a variable declared inside a for loop in > a C program is defined (memory address allocated) just once, > or if (as in Perl) a fresh (unique) memory address is used > for each iteration. C allows the implementation to do either... So I wrote this program to find out: ...so your program will only tell you what your implementation (i.e. your current version of your current compiler on your current operating system, with your current flag settings) does, and even then it only tells you what it's chosen to do for this particular translation of this particular program. It doesn't tell you anything about what other implementations will do, or even what your own implementation will do for the next program you write (or, indeed, for this same program if you were to re-compile it). <snip> > > ***** QUESTION: ***** > Is this behavior mandated by the C standard? No. > If so, where? I've been > looking, but can't find where it discusses this. That's laudable, but it takes a lot longer to find something that isn't there. :-) <snip> -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| Date | 2015-03-26 20:57 -0700 |
| Message-ID | <FJmdncGZZaS-SInInZ2dnUVZ572dnZ2d@giganews.com> |
| In reply to | #58561 |
On 3/21/2015 1:28 AM, Richard Heathfield wrote: > Robbie Hatley wrote: > > ***** QUESTION: *** > > Is this [var alloc in loop] behavior mandated by the C standard? > > No. Ah. Ok then. I was wondering about that. :-) Makes sense, actually, because it leaves compiler authors free to handle memory allocation as they see fit, and as best fits the situation (CPU, OS, program behavior, etc). -- Cheers, Robbie Hatley Midway City, CA, USA perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"' http://www.well.com/user/lonewolf/ https://www.facebook.com/robbie.hatley
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-03-21 01:29 -0700 |
| Message-ID | <87h9tewy7g.fsf@kst-u.example.com> |
| In reply to | #58560 |
Robbie Hatley <see.my.sig@for.my.address> writes:
> I was wondering if a variable declared inside a for loop in
> a C program is defined (memory address allocated) just once,
> or if (as in Perl) a fresh (unique) memory address is used
> for each iteration. So I wrote this program to find out:
>
> /* lexical-var-test.c */
> #include <stdio.h>
> int * array[12];
> int main(int argc, char *argv[])
> {
> int i = 0;
> for ( i = 1 ; i <= 10 ; ++i ) {
> int var = i;
> array[i] = &var;
> printf("Addr = %p Value = %d\n", (void*)array[i], *array[i]);
> }
> return 0;
> }
>
> And the results of running it are:
>
[snip]
>
> So while the value changes, the address stays the same, meaning that
> the variable "var" is declared & defined & allocated ONLY ON FIRST
> ITERATION; after that, only the value changes.
>
>
> ***** QUESTION: *****
> Is this behavior mandated by the C standard? If so, where? I've been
> looking, but can't find where it discusses this.
No, it's not mandated. As far as the language is concerned, a
new instance of `var` is created on entry to the enclosing block,
and ceases to exist when execution reaches the closing "}".
But "allocating" and "deallocating" a local variable doesn't have
to involve any actual run-time action. A compiler will likely
just allocation space for both `i` and `var` as part of the stack
frame on entry to main, and deallocate that space at once on exit.
It doesn't matter whether the various instances of `var` have the
same address or not, since logically no two of them exist at the
same time.
> For comparison, Perl handles variables VERY differently. Scope, duration,
> definitions, etc. Check out THIS program:
>
> use v5.014.004;
> use strict;
> use warnings;
> our @array;
> for (1..10) {
> my $var = $_;
> $array[$_] = \$var;
> }
> for (1..10) {
> say("Addr = $array[$_] Value = ${$array[$_]}");
> }
One difference (among many) between C and Perl is that in Perl, you can
save a reference to $var and refer to it outside the scope in which it's
declared. The existence of a reference means that it won't be
garbage-collected. In C, you can take the address of a local variable
and refer to it outside the variable's scope -- but doing so results in
undefined behavior.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| Date | 2015-03-26 21:01 -0700 |
| Message-ID | <FJmdncOZZaSCS4nInZ2dnUVZ572dnZ2d@giganews.com> |
| In reply to | #58562 |
On 3/21/2015 1:29 AM, Keith Thompson wrote:
> One difference (among many) between C and Perl is that in Perl, you can
> save a reference to $var and refer to it outside the scope in which it's
> declared. The existence of a reference means that it won't be
> garbage-collected.
Yep, quite useful. Used in "closures", "objects", etc.
> In C, you can take the address of a local variable and refer to it
> outside the variable's scope -- but doing so results in undefined
> behavior.
I tried doing that, only to get pointers that pointed to 0. But I
suppose there's no guarantee in C that such pointers point to
anything valid at all. Or that using them won't crash your program,
or your operating system.
Where I worked a few years ago, one programmer was fond of using
lots of fixed-size C arrays. Problem was, later, the need for storing
more data arose. So we ended up with stuff like:
/* many lines of code */
int MyArray[30];
/* many more lines of code */
int i;
for ( i= 0 ; i < 37 ; ++i)
{
MyArray[i] = SomeFunc(i);
}
/* oops, that looks dangerous, did he forget to scroll up? */
Which mostly worked just fine, believe it or not. (Though, the
programmer had to turn most of his warnings off in order to get
his error-ridden code to even compile.)
Except... just every so often... once or twice a week...
Windows (the OS on which the program was running) would suddenly,
inexplicably crash with a "general protection fault".
I'm pretty sure those crashes were due the various overruns
strewn throughout the enormous program he was maintaining.
Undefined behavior is so... undefined.
--
Cheers,
Robbie Hatley
Midway City, CA, USA
perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"'
http://www.well.com/user/lonewolf/
https://www.facebook.com/robbie.hatley
[toc] | [prev] | [next] | [standalone]
| From | asetofsymbols@gmail.com |
|---|---|
| Date | 2015-03-21 01:40 -0700 |
| Message-ID | <23d4ca0a-80fe-4193-b7f0-a58a0cf6be31@googlegroups.com> |
| In reply to | #58560 |
Robbie wrote:"
int i = 0;
for ( i = 1 ; i <= 10 ; ++i ) {
int var = i;
array[i] = &var;
printf("Addr = %p Value = %d\n", (void*)array[i], *array[i]);
}
return 0;
"
First you write: array[i] = &var;
Than what do you expect?
printf of array[i] print always
&var ...
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2015-03-21 08:43 +0000 |
| Message-ID | <cn4p8qF20elU1@mid.uni-berlin.de> |
| In reply to | #58560 |
Robbie Hatley <see.my.sig@for.my.address> wrote:
> I was wondering if a variable declared inside a for loop in
> a C program is defined (memory address allocated) just once,
> or if (as in Perl) a fresh (unique) memory address is used
> for each iteration. So I wrote this program to find out:
> /* lexical-var-test.c */
> #include <stdio.h>
> int * array[12];
> int main(int argc, char *argv[])
> {
> int i = 0;
> for ( i = 1 ; i <= 10 ; ++i ) {
> int var = i;
> array[i] = &var;
> printf("Addr = %p Value = %d\n", (void*)array[i], *array[i]);
> }
> return 0;
> }
This program doesn't tell you much about your question because
you left the most probable thing out of consideration: the loop
variable isn't anywhere in memory but just in a CPU register (or
in one of the CPU caches or perhaps even optimized out completely
if the compiler finds some way to do that). But by taking the
address of the variable you force the compiler to use a memory
location for it. And, not urprisingly, a not too stupid compiler
figures that it can use the same location for all rounds of the
loop.
> So while the value changes, the address stays the same, meaning that
> the variable "var" is declared & defined & allocated ONLY ON FIRST
> ITERATION; after that, only the value changes.
That there's some "allocation" is, in all probability, an arte-
fact of your taking the address of the loop variable.
> ***** QUESTION: *****
> Is this behavior mandated by the C standard? If so, where? I've been
> looking, but can't find where it discusses this.
Not that I know of. Why should the standard prescribe how the
compiler does its work? All the standard cares about is the
scope of the loop variable. If the compiled code satisifies
that requirement it's fine, whatever method it uses. You'll
have to look at the assembler generated to see what really
happens under the hood (and that's, of course, specific to
the compiler you use).
> For comparison, Perl handles variables VERY differently. Scope, duration,
> definitions, etc. Check out THIS program:
> use v5.014.004;
> use strict;
> use warnings;
> our @array;
> for (1..10) {
> my $var = $_;
> $array[$_] = \$var;
> }
> for (1..10) {
> say("Addr = $array[$_] Value = ${$array[$_]}");
> }
Also this, IMHO, doesn't test what you set out to prove. Again,
by taking the address of $var, storing it in an array and then
using that outside the loop you have enforced that there's some-
thing in memory and that it is kept past the end of the first
loop. If you had just used the value of $_ in the loops the
Perl interpreter could have done something different. And,
what you get via the '\' operator is not an address but a
reference, and Perl does reference counting since it has a
GC, so things are rather different from C.
> Which shows that in Perl, a variable declared in a for loop
> is re-declared & re-defined & re-allocated ON EVERY SINGLE
> ITERATION. Very, very different from C.
I'm not convinced. Moreover, the nearer equivalent of the C
program (to avoid creating additional references in the loop
bock by storing in @array, wich C doesn't do) would be
use strict;
use warnings;
print "Addr = ", \$_, " Value = $_\n" for 1..10;
And with that you will find that $_ always has the same address.
So no principle difference at all to the behaviour of the C pro-
gram... But for the details of Perl I guess comp.lang.perl.misc
will be the better place for further discussions.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| Date | 2015-03-26 20:58 -0700 |
| Message-ID | <FJmdncCZZaTjSInInZ2dnUVZ570AAAAA@giganews.com> |
| In reply to | #58564 |
On 3/21/2015 1:43 AM, Jens Thoms Toerring wrote:
> Robbie Hatley <see.my.sig@for.my.address> wrote:
> > ...
> > For comparison, Perl handles variables VERY differently. Scope, duration,
> > definitions, etc. Check out THIS program:
> >
> > use v5.014.004;
> > use strict;
> > use warnings;
> > our @array;
> > for (1..10) {
> > my $var = $_;
> > $array[$_] = \$var;
> > }
> > for (1..10) {
> > say("Addr = $array[$_] Value = ${$array[$_]}");
> > }
>
> Also this, IMHO, doesn't test what you set out to prove. Again,
> by taking the address of $var, storing it in an array and then
> using that outside the loop you have enforced that there's some-
> thing in memory and that it is kept past the end of the first
> loop. If you had just used the value of $_ in the loops the
> Perl interpreter could have done something different....
Yep, I found that out a day later when I wrote a program which
didn't store references anywhere. The variable's reference
number was then fixed (and under the hood, likely using the
same physical memory location over and over). So in Perl,
it's reference count that determines whether a variable gets
re-used or multiple copies created.
Whereas in C, there's no refs and no ref counts, and "auto"
variables declared at the top of loop blocks are reused each
iteration, and are not usable outside of the loop block in
which they were declared.
I don't recall whether it's legal to refer to the address
of C "static" variables in functions, outside the function?
I can compile and run the following without error, but I'm
dubious as to whether this may result in undefined behavior:
/* static-ref-test.c */
#include <stdio.h>
int* StatRef (void)
{
static int Fred = 17;
return &Fred;
}
int main(void)
{
int Jack = *StatRef();
printf("Jack = %d\n", Jack);
return 0;
}
--
Cheers,
Robbie Hatley
Midway City, CA, USA
perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"'
http://www.well.com/user/lonewolf/
https://www.facebook.com/robbie.hatley
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-03-27 06:12 +0000 |
| Message-ID | <mf2sb6$kor$1@dont-email.me> |
| In reply to | #59049 |
On 27/03/15 03:58, Robbie Hatley wrote:
>
<snip>
>
> I don't recall whether it's legal to refer to the address
> of C "static" variables in functions, outside the function?
Yeah, that's fine. The object exists for the whole of the program
execution time, so you're good to go.
> I can compile and run the following without error, but I'm
> dubious as to whether this may result in undefined behavior:
>
> /* static-ref-test.c */
> #include <stdio.h>
> int* StatRef (void)
> {
> static int Fred = 17;
> return &Fred;
> }
That's fine.
<snip>
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-03-26 23:32 -0700 |
| Message-ID | <87bnjfne6j.fsf@kst-u.example.com> |
| In reply to | #59049 |
Robbie Hatley <see.my.sig@for.my.address> writes:
[...]
> Whereas in C, there's no refs and no ref counts, and "auto"
> variables declared at the top of loop blocks are reused each
> iteration, and are not usable outside of the loop block in
> which they were declared.
In C, an object declared locally in a loop:
while (blah) {
int obj;
/* ... */
}
exists only for one iteration of the loop. Each iteration creates and
then destroys a distinct object named "obj". (Strictly speaking that
occurs on entry and exit to the block, which is a sub-statement of the
loop.)
In a typical C implementation, the same memory location is likely to be
used for each instance of "obj", and the allocation and deallocation
that occur on each iteration in the abstract machine are likely to be
hoisted to a higher scope as an optimization.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-03-21 10:54 +0000 |
| Message-ID | <mejiko$uvj$1@dont-email.me> |
| In reply to | #58560 |
On 21/03/2015 07:52, Robbie Hatley wrote:
>
> I was wondering if a variable declared inside a for loop in
> a C program is defined (memory address allocated) just once,
> or if (as in Perl) a fresh (unique) memory address is used
> for each iteration. So I wrote this program to find out:
> for ( i = 1 ; i <= 10 ; ++i ) {
> int var = i;
> Addr = 0x23cb0c Value = 1
> Addr = 0x23cb0c Value = 2
That proves nothing. Maybe 'var' is reallocated each time, but it just
happens that the stack pointer has the same value (and why not), and the
address happens to be the same.
And of course the compiler will take advantage of this. In fact, unless
'var' is implemented as pointer, 'var' *has* to have the same offset or
address for each iteration.
Otherwise it would be impossible to generate a single body of code for
the loop. (In your example, the loop can be unrolled, and conceivably,
each of the ten 'var's can have a different address. But for most loops
that is not practical.)
I doubt the C standard sets out how compilers should do their code
generation.
> So while the value changes, the address stays the same, meaning that
> the variable "var" is declared & defined & allocated ONLY ON FIRST
> ITERATION; after that, only the value changes.
> For comparison, Perl handles variables VERY differently. Scope, duration,
> definitions, etc. Check out THIS program:
> for (1..10) {
> my $var = $_;
> $array[$_] = \$var;
> Addr = SCALAR(0x6000aa3c8) Value = 1
> Addr = SCALAR(0x60002c198) Value = 2
More than likely, Perl variables are allocated on the heap.
> Which shows that in Perl, a variable declared in a for loop
> is re-declared & re-defined & re-allocated ON EVERY SINGLE
> ITERATION. Very, very different from C. Not better or worse,
> just very different.
No worse, given that Perl is 100 times slower than C
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-03-21 13:54 -0700 |
| Message-ID | <87d242vzoc.fsf@kst-u.example.com> |
| In reply to | #58568 |
Bartc <bc@freeuk.com> writes:
> On 21/03/2015 07:52, Robbie Hatley wrote:
>> I was wondering if a variable declared inside a for loop in
>> a C program is defined (memory address allocated) just once,
>> or if (as in Perl) a fresh (unique) memory address is used
>> for each iteration. So I wrote this program to find out:
>
>> for ( i = 1 ; i <= 10 ; ++i ) {
>> int var = i;
>
>
>> Addr = 0x23cb0c Value = 1
>> Addr = 0x23cb0c Value = 2
>
> That proves nothing. Maybe 'var' is reallocated each time, but it just
> happens that the stack pointer has the same value (and why not), and
> the address happens to be the same.
>
> And of course the compiler will take advantage of this. In fact,
> unless 'var' is implemented as pointer, 'var' *has* to have the same
> offset or address for each iteration.
No, it doesn't have to, though it's very likely to.
What's relevant to the lifetime of `var` is not the loop, but the block
within the loop, delimited by `{` and `}`. The loop itself creates a
scope, and the block creates another scope within it; objects defined in
the block have a lifetime associated with the execution of the block.
Most compilers will allocate storage for the block identically each time
it's executed, resulting in the same address for each object defined in
the block. (There's no 100% pedantically portable way to verify that,
since you can't compare addresses of objects that don't exist at the
same time while avoiding undefined behavior, but you can, for example,
print the address with printf("%p", (void*)&var).) And in fact most
compilers will optimize the allocation by doing it just once on entry to
the function.
But imagine a hypothetical compiler that physically allocates storage
for the block each time it's entered, and that allocates that storage on
something like a heap. Space for `var` would be allocated each time the
block is entered, and explicitly deallocated each time it's left -- and
the address of that storage could differ on each iteration.
> Otherwise it would be impossible to generate a single body of code for
> the loop. (In your example, the loop can be unrolled, and conceivably,
> each of the ten 'var's can have a different address. But for most
> loops that is not practical.)
Allocation for the block would update something like a frame pointer.
`var` would be accessed as an offset from the current value of the frame
pointer.
I don't suggest that this is a likely implementation, but it's perfectly
valid as far as the standard is concerned. There have been compilers
that generate code that allocates "stack" storage from something like a
heap, but I doubt that they take it down to the block level.
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Robbie Hatley <see.my.sig@for.my.address> |
|---|---|
| Date | 2015-03-26 21:24 -0700 |
| Message-ID | <Yfydnf048sr_RonInZ2dnUVZ57ydnZ2d@giganews.com> |
| In reply to | #58568 |
On 3/21/2015 3:54 AM, Bartc wrote: > ... Perl is 100 times slower than C ... While I understand and somewhat agree-with the gist of what you're saying, I must point out, that's an unfair comparison, because to actually "run" a C program -- as C -- would require a C interpreter, and suddenly your C program would be about as slow as a comparable Perl program. Each language has its own strengths and weaknesses. I've used C for small mathematical programs, encryption programs, and embedded firmware. It's good for all that and much more. (Drivers, for example. And writing operating systems. And writing interpreters for higher-level programming languages.) C sucks at certain things, though, including these two: 1. Object-oriented situations (any situation with hierarchies of classes of objects with more-specific classes inheriting attributes and methods from more-general classes). C++ is much better for this. (I've heard Java also excels at OOP, but I've yet to learn Java.) I've seen C used in object-oriented situations and the results are horrible: reams of tangled spaghetti code fit to give you nightmares. 2. Working with directories and files, especially if the files are named in Japanese, Russian, Hebrew, or Tamil. Perl excels at this, as it has facilities for dealing with files and directories, and with Unicode, built into it. No portable way to do that in C, that I know of. Though, I suppose one could find libraries to do such things. -- Cheers, Robbie Hatley Midway City, CA, USA perl -le 'print "\154o\156e\167o\154f\100w\145ll\56c\157m"' http://www.well.com/user/lonewolf/ https://www.facebook.com/robbie.hatley
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-03-27 20:35 +0000 |
| Message-ID | <mf4eu5$tet$1@speranza.aioe.org> |
| In reply to | #59051 |
Robbie Hatley <see.my.sig@for.my.address> wrote: (snip) >> ... Perl is 100 times slower than C ... > While I understand and somewhat agree-with the gist of what > you're saying, I must point out, that's an unfair comparison, > because to actually "run" a C program -- as C -- would require > a C interpreter, and suddenly your C program would be about > as slow as a comparable Perl program. I suppose, but some years ago we had a perl program that ran too slow. (A simple filter, reading/writing at about 1 megabyte per minute.) So we tried perl2c, and it was still 1 megabyte per minute. It seems that perl2c generates the same internal code, and the interpreter for that, and so runs at the same speed! Most often, when someone says "run a C program", they mean run "the result from compiling a C program", but when someone says "run a perl program" they mean either within perl, or interpreting the intermediate code that perl generates. (snip) -- glen
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-03-27 21:24 +0000 |
| Message-ID | <mf4hoc$4h9$1@dont-email.me> |
| In reply to | #59051 |
On 27/03/2015 04:24, Robbie Hatley wrote: > > On 3/21/2015 3:54 AM, Bartc wrote: > >> ... Perl is 100 times slower than C ... > > While I understand and somewhat agree-with the gist of what > you're saying, I must point out, that's an unfair comparison, > because to actually "run" a C program -- as C -- would require > a C interpreter, and suddenly your C program would be about > as slow as a comparable Perl program. No, Perl would still be slower. An interpreter for C can be fast because the language is statically typed (no runtime type dispatch), and lends itself very easily to JIT compilation. (It would also be far more feasible to make use of ASM because C operations are simple.) A Perl interpreter can't take the same advantage, and perhaps they haven't bothered about speed anyway because it is adequate for the scripts people use it for. (Maybe fast versions exist using sophisticated tracing but the version I used on the example loop /was/ about 100 times slower than C compiled to native code.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2015-03-28 00:03 +0000 |
| Message-ID | <mf4r41$njb$1@speranza.aioe.org> |
| In reply to | #59105 |
Bartc <bc@freeuk.com> wrote: >> On 3/21/2015 3:54 AM, Bartc wrote: >>> ... Perl is 100 times slower than C ... (snip) > No, Perl would still be slower. > An interpreter for C can be fast because the language is statically > typed (no runtime type dispatch), and lends itself very easily to JIT > compilation. (It would also be far more feasible to make use of ASM > because C operations are simple.) Well yes, but then it might as well be a compiler. > A Perl interpreter can't take the same advantage, and perhaps they > haven't bothered about speed anyway because it is adequate for the > scripts people use it for. (Maybe fast versions exist using > sophisticated tracing but the version I used on the example loop /was/ > about 100 times slower than C compiled to native code.) A perl interpreter could take advantage of many things in the case where they happen to be true. Just because it doesn't have static typing doesn't mean that programs have to change types dynamically, and it could run (much) faster then they don't. But yes, as far as I know existing perl doesn't do that, and is often very slow for large problems. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-03-28 10:00 +0000 |
| Message-ID | <mf5u22$nkd$1@dont-email.me> |
| In reply to | #59109 |
On 28/03/2015 00:03, glen herrmannsfeldt wrote: > Bartc <bc@freeuk.com> wrote: > >>> On 3/21/2015 3:54 AM, Bartc wrote: > >>>> ... Perl is 100 times slower than C ... > > (snip) > >> No, Perl would still be slower. > >> An interpreter for C can be fast because the language is statically >> typed (no runtime type dispatch), and lends itself very easily to JIT >> compilation. (It would also be far more feasible to make use of ASM >> because C operations are simple.) > > Well yes, but then it might as well be a compiler. There would reasons for using an interpreter for C, or something that acts like an interpreter, rather than using a traditional compiler. Being able to make an edit and then run even a large application more or less instantly is one. I'm saying that such an interpreter lends itself to a number of optimisations, while still being used as an interpreter. There's no way performance would drop two magnitudes (unless the interpreter was written in Perl; but I suspect it might still be faster!). -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Stephen Sprunk <stephen@sprunk.org> |
|---|---|
| Date | 2015-03-28 18:14 -0500 |
| Message-ID | <mf7ck2$h0e$1@dont-email.me> |
| In reply to | #59105 |
On 27-Mar-15 16:24, Bartc wrote: > An interpreter for C can be fast because the language is statically > typed (no runtime type dispatch), and lends itself very easily to > JIT compilation. (It would also be far more feasible to make use of > ASM because C operations are simple.) > > A Perl interpreter can't take the same advantage, ... Perl has had JIT compilation for at least a decade, maybe two. It's still slower than an equivalent C program for various reasons, but not as slow as you'd expect for an "interpreted" language; also, since programmer time is typically more expensive than machine time, Perl often wins anyway, especially for string processing or throwaway code. S -- Stephen Sprunk "God does not play dice." --Albert Einstein CCIE #3723 "God is an inveterate gambler, and He throws the K5SSS dice at every possible opportunity." --Stephen Hawking
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2015-03-21 14:39 +0000 |
| Message-ID | <20150321073009.274@kylheku.com> |
| In reply to | #58560 |
On 2015-03-21, Robbie Hatley <see.my.sig@for.my.address> wrote: > > I was wondering if a variable declared inside a for loop in > a C program is defined (memory address allocated) just once, > or if (as in Perl) a fresh (unique) memory address is used > for each iteration. Firstly this difference is irrelevant in C, because C doesn't have lexical closures. The difference is highly relevant in a language with lexical closures (and if the variable is mutated). Why? Suppose that your loop body creates lexical closures and stashes them somewhere. If there is only one instance of the variable, all of the closures share that variable. If one closure modifies the variable, all the other closures witness the modification. If each iteration has a new instance of the variable, then the lexical closures do not exhibit this sharing; the modification to the variable is private. Secondly, just because you don't get the same address doesn't mean it is the same variable. In the semantics of C, the non-static local variable ceases to exist when the enclosing block terminates. A new instance of the block may allocate the variable into the same address. For the repeated iterations of the same loop in the same invocation of the function, this re-use is likely because of the way C is compiled. The re-use does not indicate that the object is the same variable any more than a re-used address coming out of malloc indicates that the object is the same thing as whatever it was before. So, C in fact freshly instantiates the variable, possibly in the same memory location rather than a unique one. Local variables can be treated this way in C because, again, it doesn't have lexical closures. (However, C has pointers, and pointers to local variables can endure when those variables are gone, leading to bugs.)
[toc] | [prev] | [next] | [standalone]
| From | fir <profesor.fir@gmail.com> |
|---|---|
| Date | 2015-03-21 09:40 -0700 |
| Message-ID | <549b9428-b003-49c2-8717-29df56854dc9@googlegroups.com> |
| In reply to | #58560 |
W dniu sobota, 21 marca 2015 08:52:20 UTC+1 użytkownik Robbie Hatley napisał:
> I was wondering if a variable declared inside a for loop in
> a C program is defined (memory address allocated) just once,
> or if (as in Perl) a fresh (unique) memory address is used
> for each iteration. So I wrote this program to find out:
>
> /* lexical-var-test.c */
> #include <stdio.h>
> int * array[12];
> int main(int argc, char *argv[])
> {
> int i = 0;
> for ( i = 1 ; i <= 10 ; ++i ) {
> int var = i;
> array[i] = &var;
> printf("Addr = %p Value = %d\n", (void*)array[i], *array[i]);
> }
> return 0;
> }
>
> And the results of running it are:
>
> Addr = 0x23cb0c Value = 1
> Addr = 0x23cb0c Value = 2
> Addr = 0x23cb0c Value = 3
> Addr = 0x23cb0c Value = 4
> Addr = 0x23cb0c Value = 5
> Addr = 0x23cb0c Value = 6
> Addr = 0x23cb0c Value = 7
> Addr = 0x23cb0c Value = 8
> Addr = 0x23cb0c Value = 9
> Addr = 0x23cb0c Value = 10
>
> So while the value changes, the address stays the same, meaning that
> the variable "var" is declared & defined & allocated ONLY ON FIRST
> ITERATION; after that, only the value changes.
>
>
it was also confusing me when i dirst was learning c (in 2000 or 2001)
but no
for(int i=0; i<100; i++)
{
int local = 2;
local++;
}
here the instancing of variable is not
repeated (the variable isnt even created at the entering the block then dropped
on exiting)
it is a bit confusing as assignment (= 2)
is repeated (afaik)
(i am probably not a big fan of puting args and locals on the stack in c progs,
holding it all static couled be maybe probably better (maybe small executables, maybe faster and maybe more space for some 'weird' techniques to use)
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web