Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #167065 > unrolled thread
| Started by | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| First post | 2022-08-19 10:22 -0700 |
| Last post | 2022-08-19 18:47 -0700 |
| Articles | 11 — 6 participants |
Back to article view | Back to comp.lang.c
variable addresses on the stack Thiago Adams <thiago.adams@gmail.com> - 2022-08-19 10:22 -0700
Re: variable addresses on the stack Thiago Adams <thiago.adams@gmail.com> - 2022-08-19 10:27 -0700
Re: variable addresses on the stack Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-08-19 10:59 -0700
Re: variable addresses on the stack Thiago Adams <thiago.adams@gmail.com> - 2022-09-21 05:09 -0700
Re: variable addresses on the stack Thiago Adams <thiago.adams@gmail.com> - 2022-09-21 05:18 -0700
Re: variable addresses on the stack Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-21 15:30 -0700
Re: variable addresses on the stack David Brown <david.brown@hesbynett.no> - 2022-09-21 15:34 +0200
Re: variable addresses on the stack Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-09-21 15:23 -0700
Re: variable addresses on the stack Kaz Kylheku <480-992-1380@kylheku.com> - 2022-08-19 20:58 +0000
Re: variable addresses on the stack Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2022-08-19 15:47 -0600
Re: variable addresses on the stack Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-08-19 18:47 -0700
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2022-08-19 10:22 -0700 |
| Subject | variable addresses on the stack |
| Message-ID | <54f99ed2-fe4d-4cab-944c-cb61799d64ecn@googlegroups.com> |
I am curious with the following..
void f(int i) {
if (i > 1) {
int j ='a';
}
if (i < 1) {
int k ='b';
}
}
When I see the assembly ouput I can see the compiler
use the address rbp-4 for j and rbp-8 for k
Why not the same address considering that j and k don't exist
at the same time?
Any reason?
[toc] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2022-08-19 10:27 -0700 |
| Message-ID | <88b71bc9-2e48-4f58-a0f5-6b17e4c5f0f6n@googlegroups.com> |
| In reply to | #167065 |
Also.. Was this block scopes variables valid in previous versions of C? I tried gcc -std=c89 and it works.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-08-19 10:59 -0700 |
| Message-ID | <871qtc868m.fsf@nosuchdomain.example.com> |
| In reply to | #167065 |
Thiago Adams <thiago.adams@gmail.com> writes:
> I am curious with the following..
>
> void f(int i) {
> if (i > 1) {
> int j ='a';
> }
> if (i < 1) {
> int k ='b';
> }
> }
> When I see the assembly ouput I can see the compiler
> use the address rbp-4 for j and rbp-8 for k
>
> Why not the same address considering that j and k don't exist
> at the same time?
> Any reason?
No particular reason. They don't exist at the same time, and
a compiler certainly *could* allocate them at the same address.
It's valid either way as long as the code behaves correctly.
I played with it myself. With gcc -O0, I got the same result
you did. With -O1 and higher, it eliminated j and k. When I
added putchar calls to prevent that, they were both stored in the
same register.
When I changed j and k to arrays, gcc -O0 allocated them at the
same address.
And yes, block local variables have been supported for a long time.
A 1975 C reference manual allowed declarations only at the top of
a function body, but K&R1 (1978) allows declarations within any
compound statement.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2022-09-21 05:09 -0700 |
| Message-ID | <f2dfb3b5-379f-42d8-9bdc-99051a56d7e0n@googlegroups.com> |
| In reply to | #167067 |
On Friday, August 19, 2022 at 2:59:21 PM UTC-3, Keith Thompson wrote:
> Thiago Adams <thiago...@gmail.com> writes:
> > I am curious with the following..
> >
> > void f(int i) {
> > if (i > 1) {
> > int j ='a';
> > }
> > if (i < 1) {
> > int k ='b';
> > }
> > }
>
[...]
> And yes, block local variables have been supported for a long time.
> A 1975 C reference manual allowed declarations only at the top of
> a function body, but K&R1 (1978) allows declarations within any
> compound statement.
C99 added "mixed declarations and code"
I changed the code adding variable 'm'
void f(int i) {
if (i > 1) {
int j ='a';
}
if (i < 1) {
int k ='b';
}
int m = 1;
}
gcc with -std=c90 -pedantic
gives:
"warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement]"
int l = 1;
^
So, block declarations is something very old, but "mixed" declarations are new
in C99.
Very weird because adding { } around the "mixed" declaration it just works.
I cannot see a reason for this limitation, but I guess compilers use to accept
mixed declarations for a long time.
void f(int i) {
if (i > 1) {
int j ='a';
}
if (i < 1) {
int k ='b';
}
{
int m = 1;
}
}
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2022-09-21 05:18 -0700 |
| Message-ID | <50c4530a-b411-4ceb-8b8c-2181a15afd8fn@googlegroups.com> |
| In reply to | #167772 |
On Wednesday, September 21, 2022 at 9:09:15 AM UTC-3, Thiago Adams wrote:
> On Friday, August 19, 2022 at 2:59:21 PM UTC-3, Keith Thompson wrote:
> > Thiago Adams <thiago...@gmail.com> writes:
> > > I am curious with the following..
> > >
> > > void f(int i) {
> > > if (i > 1) {
> > > int j ='a';
> > > }
> > > if (i < 1) {
> > > int k ='b';
> > > }
> > > }
> >
> [...]
> > And yes, block local variables have been supported for a long time.
> > A 1975 C reference manual allowed declarations only at the top of
> > a function body, but K&R1 (1978) allows declarations within any
> > compound statement.
> C99 added "mixed declarations and code"
>
> I changed the code adding variable 'm'
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
> int m = 1;
> }
>
> gcc with -std=c90 -pedantic
> gives:
>
> "warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement]"
> int l = 1;
> ^
> So, block declarations is something very old, but "mixed" declarations are new
> in C99.
>
> Very weird because adding { } around the "mixed" declaration it just works.
> I cannot see a reason for this limitation, but I guess compilers use to accept
> mixed declarations for a long time.
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
> {
> int m = 1;
> }
> }
I added C89 target in my transpiler, so I am writing
here
https://github.com/thradams/cake/blob/main/manual.md
changes since C89 and how we can write (if possible) the
equivalent code in previous versions.
C99 added Flexible array members
struct s {
int n;
double d[];
};
Does anyone have suggestion how to write this in C89?
struct s {
int n;
double d[1]; //maybe?
};
The sizeof a struct with flexible array members is not not clear..
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-09-21 15:30 -0700 |
| Message-ID | <878rmcfjik.fsf@nosuchdomain.example.com> |
| In reply to | #167773 |
Thiago Adams <thiago.adams@gmail.com> writes:
[...]
> C99 added Flexible array members
>
> struct s {
> int n;
> double d[];
> };
>
> Does anyone have suggestion how to write this in C89?
>
> struct s {
> int n;
> double d[1]; //maybe?
> };
>
> The sizeof a struct with flexible array members is not not clear..
The (questionably legal) predecessor to flexible array members was
known as the "struct hack". See question 2.6 of the comp.lang.c FAQ.
https://www.c-faq.com/
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-09-21 15:34 +0200 |
| Message-ID | <tgf3t6$1r02t$1@dont-email.me> |
| In reply to | #167772 |
On 21/09/2022 14:09, Thiago Adams wrote:
> On Friday, August 19, 2022 at 2:59:21 PM UTC-3, Keith Thompson wrote:
>> Thiago Adams <thiago...@gmail.com> writes:
>>> I am curious with the following..
>>>
>>> void f(int i) {
>>> if (i > 1) {
>>> int j ='a';
>>> }
>>> if (i < 1) {
>>> int k ='b';
>>> }
>>> }
>>
> [...]
>> And yes, block local variables have been supported for a long time.
>> A 1975 C reference manual allowed declarations only at the top of
>> a function body, but K&R1 (1978) allows declarations within any
>> compound statement.
>
> C99 added "mixed declarations and code"
>
> I changed the code adding variable 'm'
>
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
>
> int m = 1;
> }
>
> gcc with -std=c90 -pedantic
> gives:
>
> "warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement]"
> int l = 1;
> ^
> So, block declarations is something very old, but "mixed" declarations are new
> in C99.
>
> Very weird because adding { } around the "mixed" declaration it just works.
> I cannot see a reason for this limitation, but I guess compilers use to accept
> mixed declarations for a long time.
>
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
> {
> int m = 1;
> }
> }
C90 (and I believe before that too - but I am not well versed in
pre-ANSI C rules) allowed the definition of variables at the start of a
block, but not after statements. There was no requirement for the
common practice of bunching all the definitions at the start of a
function. And the initialisation for the variables could have function
calls and anything else.
C99 allowed declarations and statements to be freely mixed, which let
people write nicer code. But your second version there, with "int m =
1;" inside braces, is perfectly fine C90.
I don't know what the historic justification for C90's limitations here
was - perhaps it made the language syntax easier to describe, or made
"dumb translator" compilers easier to write, or perhaps it simply
reflected the style of code structure that was popular at the time (it
matches Pascal, for instance).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-09-21 15:23 -0700 |
| Message-ID | <87czbofjtw.fsf@nosuchdomain.example.com> |
| In reply to | #167772 |
Thiago Adams <thiago.adams@gmail.com> writes:
> On Friday, August 19, 2022 at 2:59:21 PM UTC-3, Keith Thompson wrote:
>> Thiago Adams <thiago...@gmail.com> writes:
>> > I am curious with the following..
>> >
>> > void f(int i) {
>> > if (i > 1) {
>> > int j ='a';
>> > }
>> > if (i < 1) {
>> > int k ='b';
>> > }
>> > }
>>
> [...]
>> And yes, block local variables have been supported for a long time.
>> A 1975 C reference manual allowed declarations only at the top of
>> a function body, but K&R1 (1978) allows declarations within any
>> compound statement.
>
> C99 added "mixed declarations and code"
>
> I changed the code adding variable 'm'
>
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
>
> int m = 1;
> }
>
> gcc with -std=c90 -pedantic
> gives:
>
> "warning: mixing declarations and code is a C99 extension [-Wdeclaration-after-statement]"
> int l = 1;
> ^
> So, block declarations is something very old, but "mixed" declarations are new
> in C99.
>
> Very weird because adding { } around the "mixed" declaration it just works.
> I cannot see a reason for this limitation, but I guess compilers use to accept
> mixed declarations for a long time.
>
> void f(int i) {
>
> if (i > 1) {
> int j ='a';
> }
>
> if (i < 1) {
> int k ='b';
> }
> {
> int m = 1;
> }
> }
There's nothing weird about it. C89, and older versions going back at
least to K&R1 C (1978), allowed zero or more declarations followed by
zero or more statements within a block. By adding { } you created a
block, which can begin with a declaration. (Of course your `int j` is
not visible outside the block, and nothing refers to it, so you might
get a warning about an unused variable.) The C99 change was to allow
declarations and statements to be mixed within a block.
It was only some very old versions of C (1975 and earlier) that allowed
declarations only within the top-level block of a function definition.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <480-992-1380@kylheku.com> |
|---|---|
| Date | 2022-08-19 20:58 +0000 |
| Message-ID | <20220819135226.125@kylheku.com> |
| In reply to | #167065 |
On 2022-08-19, Thiago Adams <thiago.adams@gmail.com> wrote:
> I am curious with the following..
>
> void f(int i) {
> if (i > 1) {
> int j ='a';
> }
> if (i < 1) {
> int k ='b';
> }
> }
> When I see the assembly ouput I can see the compiler
> use the address rbp-4 for j and rbp-8 for k
>
> Why not the same address considering that j and k don't exist
> at the same time?
> Any reason?
Nothing exists in the above; it is indistinguishable from
void f(int i) { }
and in the ideal circumstances, the optimized treatment
of it would be indistinguisahble from the like treatment
of the above.
If there is a difference, the compiler is not being operated in a way
which best reveals its abilities to remove dead code, or else is
somewhat lacking in those abilities.
--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
[toc] | [prev] | [next] | [standalone]
| From | Joe Pfeiffer <pfeiffer@cs.nmsu.edu> |
|---|---|
| Date | 2022-08-19 15:47 -0600 |
| Message-ID | <1b35drsy66.fsf@pfeifferfamily.net> |
| In reply to | #167065 |
Thiago Adams <thiago.adams@gmail.com> writes:
> I am curious with the following..
>
> void f(int i) {
> if (i > 1) {
> int j ='a';
> }
> if (i < 1) {
> int k ='b';
> }
> }
> When I see the assembly ouput I can see the compiler
> use the address rbp-4 for j and rbp-8 for k
>
> Why not the same address considering that j and k don't exist
> at the same time?
> Any reason?
Easier to just allocate more space and not keep track of variable
lifetimes. A compiler that was optimizing for space might decide to use
the same location for both.
Likelier would be for an optimizing compiler to notice the function has
no observable behavior and optimize the whole thing away.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-08-19 18:47 -0700 |
| Message-ID | <tdpef2$1p1m4$1@dont-email.me> |
| In reply to | #167065 |
On 8/19/2022 10:22 AM, Thiago Adams wrote:
> void f(int i) {
> if (i > 1) {
> int j ='a';
> }
> if (i < 1) {
> int k ='b';
> }
> }
You are most certainly building your code in "debug" configuration. In
which case the compiler might deliberately assign different addresses to
these variables for some more-or-less justified debugging purposes. E.g.
it might be easier to identify how a dangling pointer became dangling
when it used to point to a local variable with a unique address.
Or it might do it simply because it is easier in the current implementation.
And self-respecting compiler will discard the code inside `f` entirely,
when working in any "serious" compilation mode.
--
Best regards,
Andrey
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web