Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no,
and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
If you followed the thread you'd have realised that isn't an issue
anymore: if you use a C23 compiler. Somebody actually took this >'non-problem' and persuaded the C committee to fix it.
On 25/05/2026 14:46, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word".˙ Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code
fragment:
˙˙˙˙ void foo(void) {
˙˙˙˙/* stuff */
˙˙˙˙{˙˙˙ /* Enter an "extra" block */
˙˙˙˙int i = 42;˙˙˙ /* 'i' is allocated on the stack */
˙˙˙˙/* stuff */
˙˙˙˙if (someCond) goto OutOfHere;
˙˙˙˙/* more stuff */
˙˙˙˙}˙˙˙ /* End of "extra" block */
˙˙˙˙ OutOfHere: puts("Got to OutOfHere");
˙˙˙˙ }˙˙˙ /* End of foo() */
Now suppose someCond is true and the branch is taken.˙ Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
You'll have to wait until the experts chime in to answer that.
Usually, simple variables like this may be allocated on the stack, but
that merely consists of an offset within the stack frame that is
allocated on function entry. It may share that slot with other variables whose lifetimes don't overlap with 'i'.
No actual allocation or deallocation is done, so there is no problem.
[...]
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code >fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Personally I wouldn't worry too much about, the compiler is going
to do the right thing and speculating whether or when variables
get allocated and ...
In article <slrn1118t24.6gi.andrews@sdf.org>,
Andrew Smallshaw <andrews@sdf.org> wrote:
...
Personally I wouldn't worry too much about, the compiler is going
to do the right thing and speculating whether or when variables
get allocated and ...
But that's the whole point of this NG. That C is *not* a "safe" language.
That getting it to compile is only the first step in having any idea that
it will behave sensibly. I.e., you have to both know and follow the rules
in order to be confident that you haven't done something stupid.
Or, to put it another way, that, no, you can't rely on the compiler "doing the right thing", if you've violated some obscure rule.
[...]
Or, to put it another way, that, no, you can't rely on the compiler "doing >> the right thing", if you've violated some obscure rule.
...but I think another post down-thread addresses the original question >sufficiently.
In article <10v1vmr$1s757$7@dont-email.me>,
Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote:
...
Or, to put it another way, that, no, you can't rely on the compiler "doing >>> the right thing", if you've violated some obscure rule.
...but I think another post down-thread addresses the original question
sufficiently.
Agreed. I think I've got my answer.
When you get right down to it, as long as you can be sure it is deallocated (however you choose to define that term) when the function exits, then there's really nothing to worry about.
I can imagine a few tests, though, that might be interesting. Like having
a million or so blocks like this, and have each one jump out from the
middle. And then you could keep track of how things are going by printing out the address of i (using printf and %p) and see if they are the same or different.
Might be a fun thing to do on a rainy day...
In article <10v1jrr$35gqh$2@news.xmission.com>,
Kenny McCormack <gazelle@shell.xmission.com> wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer >>discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and >>also on some of my own code, I got to wondering about the following code >>fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable >>'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
The variable `i` will be deallocated, yes. But if the question
is whether that happens immediately after the `goto` or not,
then it's that's a different question.
The standard says that if a variable with "automatic storage
duration" is not a VLA (which describes `i` in this case), then
the lifetime of the object ends when "execution of that block
ends in any way" (sec 6.2.4 of the various standards; para 6 in
n3220).
Here, "lifetime" is defined as, "the portion of program
execution during which storage is guaranteed to be reserved for
it."
So whether or not the storage is _immediately_ reclaimed is
another matter; it may be immediately deallocated after exiting
the block, or when the function returns, or some other time.
Note that in most/all "scripting" languages, this code pattern would be a >>big no-no, and if you did it enough times, it will blow up the program.
Huh. Which languages?
Note, BTW, that we could make this issue go away by putting OutOfHere a >>line earlier - i.e., inside the "extra" block - but then we'd run into >>Bart's issue (i.e., we'd have to put an extra ';' after the label).
It actually doesn't change the issue at all; whether "execution"
of the block ends due to a `goto` out of it or reaching the end
of the block as written is irrelevant: it'll be deallocated
regardless. But whether that happens immediately or not is
another matter.
Assuming a stack-based implementation, I'd assume most compilers
would deallocate it when the enclosing function returns.
In believe in most cases, the compiler simply adds the required
storage space for all variables defined in inner-blocks to the
initial stack allocation on function entry. Which is all "deallocated"
when the function returns.
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <10v1jrr$35gqh$2@news.xmission.com>,
Kenny McCormack <gazelle@shell.xmission.com> wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer >>>discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and >>>also on some of my own code, I got to wondering about the following code >>>fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable >>>'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
The variable `i` will be deallocated, yes. But if the question
is whether that happens immediately after the `goto` or not,
then it's that's a different question.
The standard says that if a variable with "automatic storage
duration" is not a VLA (which describes `i` in this case), then
the lifetime of the object ends when "execution of that block
ends in any way" (sec 6.2.4 of the various standards; para 6 in
n3220).
Here, "lifetime" is defined as, "the portion of program
execution during which storage is guaranteed to be reserved for
it."
So whether or not the storage is _immediately_ reclaimed is
another matter; it may be immediately deallocated after exiting
the block, or when the function returns, or some other time.
Note that in most/all "scripting" languages, this code pattern would be a >>>big no-no, and if you did it enough times, it will blow up the program.
Huh. Which languages?
Note, BTW, that we could make this issue go away by putting OutOfHere a >>>line earlier - i.e., inside the "extra" block - but then we'd run into >>>Bart's issue (i.e., we'd have to put an extra ';' after the label).
It actually doesn't change the issue at all; whether "execution"
of the block ends due to a `goto` out of it or reaching the end
of the block as written is irrelevant: it'll be deallocated
regardless. But whether that happens immediately or not is
another matter.
Assuming a stack-based implementation, I'd assume most compilers
would deallocate it when the enclosing function returns.
In believe in most cases, the compiler simply adds the required
storage space for all variables defined in inner-blocks to the
initial stack allocation on function entry. Which is all "deallocated"
when the function returns. Indeed, I believe that the storage
reserved for inner block variables can be repurposed and used
in subsequent inner-blocks that have local variables in the same
function.
In article <DY%QR.370372$gO1.309583@fx14.iad>,
Scott Lurndal <slp53@pacbell.net> wrote:
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <10v1jrr$35gqh$2@news.xmission.com>,
Kenny McCormack <gazelle@shell.xmission.com> wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer >>>>discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and >>>>also on some of my own code, I got to wondering about the following code >>>>fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable >>>>'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
The variable `i` will be deallocated, yes. But if the question
is whether that happens immediately after the `goto` or not,
then it's that's a different question.
The standard says that if a variable with "automatic storage
duration" is not a VLA (which describes `i` in this case), then
the lifetime of the object ends when "execution of that block
ends in any way" (sec 6.2.4 of the various standards; para 6 in
n3220).
Here, "lifetime" is defined as, "the portion of program
execution during which storage is guaranteed to be reserved for
it."
So whether or not the storage is _immediately_ reclaimed is
another matter; it may be immediately deallocated after exiting
the block, or when the function returns, or some other time.
Note that in most/all "scripting" languages, this code pattern would be a >>>>big no-no, and if you did it enough times, it will blow up the program.
Huh. Which languages?
Note, BTW, that we could make this issue go away by putting OutOfHere a >>>>line earlier - i.e., inside the "extra" block - but then we'd run into >>>>Bart's issue (i.e., we'd have to put an extra ';' after the label).
It actually doesn't change the issue at all; whether "execution"
of the block ends due to a `goto` out of it or reaching the end
of the block as written is irrelevant: it'll be deallocated
regardless. But whether that happens immediately or not is
another matter.
Assuming a stack-based implementation, I'd assume most compilers
would deallocate it when the enclosing function returns.
In believe in most cases, the compiler simply adds the required
storage space for all variables defined in inner-blocks to the
initial stack allocation on function entry. Which is all "deallocated"
when the function returns. Indeed, I believe that the storage
reserved for inner block variables can be repurposed and used
in subsequent inner-blocks that have local variables in the same
function.
Almost certainly, yes. Of course there are some exceptions, but
the vast bulk of real-world implementations will use a stack and
likely do exactly what you just said. And on exit, deallocating
a stack frame may as simple as a single instruction.
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <DY%QR.370372$gO1.309583@fx14.iad>,
Scott Lurndal <slp53@pacbell.net> wrote:
cross@spitfire.i.gajendra.net (Dan Cross) writes:
In article <10v1jrr$35gqh$2@news.xmission.com>,
Kenny McCormack <gazelle@shell.xmission.com> wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and >>>>> also on some of my own code, I got to wondering about the following code >>>>> fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable >>>>> 'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
The variable `i` will be deallocated, yes. But if the question
is whether that happens immediately after the `goto` or not,
then it's that's a different question.
The standard says that if a variable with "automatic storage
duration" is not a VLA (which describes `i` in this case), then
the lifetime of the object ends when "execution of that block
ends in any way" (sec 6.2.4 of the various standards; para 6 in
n3220).
Here, "lifetime" is defined as, "the portion of program
execution during which storage is guaranteed to be reserved for
it."
So whether or not the storage is _immediately_ reclaimed is
another matter; it may be immediately deallocated after exiting
the block, or when the function returns, or some other time.
Note that in most/all "scripting" languages, this code pattern would be a >>>>> big no-no, and if you did it enough times, it will blow up the program. >>>>Huh. Which languages?
Note, BTW, that we could make this issue go away by putting OutOfHere a >>>>> line earlier - i.e., inside the "extra" block - but then we'd run into >>>>> Bart's issue (i.e., we'd have to put an extra ';' after the label).
It actually doesn't change the issue at all; whether "execution"
of the block ends due to a `goto` out of it or reaching the end
of the block as written is irrelevant: it'll be deallocated
regardless. But whether that happens immediately or not is
another matter.
Assuming a stack-based implementation, I'd assume most compilers
would deallocate it when the enclosing function returns.
In believe in most cases, the compiler simply adds the required
storage space for all variables defined in inner-blocks to the
initial stack allocation on function entry. Which is all "deallocated"
when the function returns. Indeed, I believe that the storage
reserved for inner block variables can be repurposed and used
in subsequent inner-blocks that have local variables in the same
function.
Almost certainly, yes. Of course there are some exceptions, but
the vast bulk of real-world implementations will use a stack and
likely do exactly what you just said. And on exit, deallocating
a stack frame may as simple as a single instruction.
Experimenting with gcc (4.8.3, 14.2.1) shows that the
stack layout depends on -O.
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label)
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
- Dan C.
I used to write assembly language on IBM 370s and Fortran on IBM
3090s. No stack that I know of.
On Tue, 26 May 2026 22:51:02 -0500, Lynn McGuire wrote:
I used to write assembly language on IBM 370s and Fortran on IBM
3090s. No stack that I know of.
IBM architectures never had a hardware stack. The POWER/PowerPC ABI
defines a stack, but that?s purely a software convention.
On 5/26/2026 7:23 PM, Dan Cross wrote:
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
I used to write assembly language on IBM 370s and Fortran on IBM 3090s.
No stack that I know of. My prof in my IBM 370 assembly language class >taught us how to create a simulated stack.
I have no idea about modern IBM mainframes. I don't even know what
their model number is.
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code fragment:
void foo(void) {
/* stuff */
{ /* Enter an "extra" block */
int i = 42; /* 'i' is allocated on the stack */
/* stuff */
if (someCond) goto OutOfHere;
/* more stuff */
} /* End of "extra" block */
OutOfHere: puts("Got to OutOfHere");
} /* End of foo() */
Now suppose someCond is true and the branch is taken. Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
In article <10v5pn8$2guem$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/26/2026 7:23 PM, Dan Cross wrote:
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
I used to write assembly language on IBM 370s and Fortran on IBM 3090s.
No stack that I know of. My prof in my IBM 370 assembly language class >>taught us how to create a simulated stack.
I have no idea about modern IBM mainframes. I don't even know what
their model number is.
Mainframes are the primary example I was thinking of. Btw, the
latest incarnation of IBM's S/360/370/390 line is called
"z/Architecture" and the z17 is the current top-of-the-line
offering from Big Blue.
Kenny McCormack pisze:
Trigger Warning: This post contains the dreaded "s word".˙ Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code
fragment:
˙˙˙˙ void foo(void) {
˙˙˙˙/* stuff */
˙˙˙˙{˙˙˙ /* Enter an "extra" block */
˙˙˙˙int i = 42;˙˙˙ /* 'i' is allocated on the stack */
˙˙˙˙/* stuff */
˙˙˙˙if (someCond) goto OutOfHere;
˙˙˙˙/* more stuff */
˙˙˙˙}˙˙˙ /* End of "extra" block */
˙˙˙˙ OutOfHere: puts("Got to OutOfHere");
˙˙˙˙ }˙˙˙ /* End of foo() */
Now suppose someCond is true and the branch is taken.˙ Does the variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
its not answer to thsi question but imo nested scopes in functions practicaly imo have rather no to much big sense (imo for example fact
that afair if and for loop have its on scope is most probably an error/mistake..is and loops are so called lightweight control structures
not searate material scopes
On 27/05/2026 14:33, fir wrote:
Kenny McCormack pisze:
Trigger Warning: This post contains the dreaded "s word".˙ Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and
also on some of my own code, I got to wondering about the following code >>> fragment:
˙˙˙˙ void foo(void) {
˙˙˙˙/* stuff */
˙˙˙˙{˙˙˙ /* Enter an "extra" block */
˙˙˙˙int i = 42;˙˙˙ /* 'i' is allocated on the stack */
˙˙˙˙/* stuff */
˙˙˙˙if (someCond) goto OutOfHere;
˙˙˙˙/* more stuff */
˙˙˙˙}˙˙˙ /* End of "extra" block */
˙˙˙˙ OutOfHere: puts("Got to OutOfHere");
˙˙˙˙ }˙˙˙ /* End of foo() */
Now suppose someCond is true and the branch is taken.˙ Does the variable >>> 'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would
be a
big no-no, and if you did it enough times, it will blow up the program.
Note, BTW, that we could make this issue go away by putting OutOfHere a
line earlier - i.e., inside the "extra" block - but then we'd run into
Bart's issue (i.e., we'd have to put an extra ';' after the label).
its not answer to thsi question but imo nested scopes in functions
practicaly imo have rather no to much big sense (imo for example fact
that afair if and for loop have its on scope is most probably an
error/mistake..is and loops are so called lightweight control
structures not searate material scopes
I don't know why so many functions make such a big deal of this.
As it is, C has one scope outside a function, and an UNLIMITED number
inside a function, for a language which averages 3 locals per function.
You can this do at file scope:
˙ static int abc˙˙˙˙˙˙˙ // local to each file
or:
˙ int abc;˙˙˙˙˙˙˙˙˙˙˙˙˙ // exported or imported
Each FILE can only contain one possible definition or declaration 'abc'.
But every function in every file can define an unlimited number of definitions of 'abc' in multiple block scopes.
The priorities are back to front!
In languages with namespaces and modules, you can have 100 modules each exporting a different 'abc', and each can be accessed from any other
module.
Bart pisze:
On 27/05/2026 14:33, fir wrote:
Kenny McCormack pisze:
Trigger Warning: This post contains the dreaded "s word".˙ Viewer
discretion advised.
Based on some recent threads (mostly, the Bart vs. The World ones), and >>>> also on some of my own code, I got to wondering about the following
code
fragment:
˙˙˙˙ void foo(void) {
˙˙˙˙/* stuff */
˙˙˙˙{˙˙˙ /* Enter an "extra" block */
˙˙˙˙int i = 42;˙˙˙ /* 'i' is allocated on the stack */
˙˙˙˙/* stuff */
˙˙˙˙if (someCond) goto OutOfHere;
˙˙˙˙/* more stuff */
˙˙˙˙}˙˙˙ /* End of "extra" block */
˙˙˙˙ OutOfHere: puts("Got to OutOfHere");
˙˙˙˙ }˙˙˙ /* End of foo() */
Now suppose someCond is true and the branch is taken.˙ Does the
variable
'i' get deallocated (i.e., the stack pointer re-adjusted) ?
Is this guaranteed to work?
Note that in most/all "scripting" languages, this code pattern would
be a
big no-no, and if you did it enough times, it will blow up the program. >>>>
Note, BTW, that we could make this issue go away by putting OutOfHere a >>>> line earlier - i.e., inside the "extra" block - but then we'd run into >>>> Bart's issue (i.e., we'd have to put an extra ';' after the label).
its not answer to thsi question but imo nested scopes in functions
practicaly imo have rather no to much big sense (imo for example fact
that afair if and for loop have its on scope is most probably an
error/mistake..is and loops are so called lightweight control
structures not searate material scopes
I don't know why so many functions make such a big deal of this.
As it is, C has one scope outside a function, and an UNLIMITED number
inside a function, for a language which averages 3 locals per function.
You can this do at file scope:
˙˙ static int abc˙˙˙˙˙˙˙ // local to each file
or:
˙˙ int abc;˙˙˙˙˙˙˙˙˙˙˙˙˙ // exported or imported
Each FILE can only contain one possible definition or declaration 'abc'.
But every function in every file can define an unlimited number of
definitions of 'abc' in multiple block scopes.
The priorities are back to front!
In languages with namespaces and modules, you can have 100 modules
each exporting a different 'abc', and each can be accessed from any
other module.
ye i forgot about this static, so you hae 3 scopes, [1] local to
function (well yet this [2] local to block afair (so 4) which in most
cases is imo probably not needed/confusing..[3] module internal/global interna; [4] module external/global external (as far as i remember, in
fact i was heavy break in coding)
i mean this may be a consequence of fact that c comes from 1970 when
modules was small (i thing whole 20 years like 1970-1990 was like mostly
8 bit era)
later before AI i was able to code 9k lines a month (all i include in
one by includes of .c files and this compiles about 1s so no need to
divide and slow my work...after AI era the speedup of coding increased
- i not measured it but it seem to be like 4x maybe 5x speedup (thus
40-50k lines a month...maybe more maybe less..but still 40k lines source compiles fast
and now is different situation and you got many logical files in one
big scope so situation is new imo and at least something like real file
scope could be handy imo... thise name "namespace" i rather dislike but
if some could be able to define scopes it would be something like
namespace probably (though i dont know what it could be
for example some may think if now you use include .c files (as far as i remember you and i prefer this way) then some could say those includes
form a tree of includes (cos you can inlude in shallow but you may
include in includes etc - if so there are 3 options of file scope
1) this file only scope
2) this file and files included (tt is here and down)
3) this file and file who includes it (its here and upp)
not saying this would be usefull but there is such possibility
splitting code on files is imo quite practical and im not sure its
good that c allows you to open { in one file and close it } in included one.. this is very raw
if treating files more seriously you could name then np
file main;˙ // names this file
and maybe such files could even be in some way better than modules in
some way (eventually there could be mechanism to treat file as module externally
On 5/26/2026 7:23 PM, Dan Cross wrote:
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire˙ <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word".˙ Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack".˙ The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK.˙ However, in practice
most systems use one; there are a handful of exceptions however.
˙˙˙˙- Dan C.
I used to write assembly language on IBM 370s and Fortran on IBM 3090s.
No stack that I know of.˙ My prof in my IBM 370 assembly language class taught us how to create a simulated stack.
In article <10v5pn8$2guem$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/26/2026 7:23 PM, Dan Cross wrote:
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
I used to write assembly language on IBM 370s and Fortran on IBM 3090s.
No stack that I know of. My prof in my IBM 370 assembly language class
taught us how to create a simulated stack.
I have no idea about modern IBM mainframes. I don't even know what
their model number is.
Mainframes are the primary example I was thinking of. Btw, the
latest incarnation of IBM's S/360/370/390 line is called
"z/Architecture" and the z17 is the current top-of-the-line
offering from Big Blue.
... imo nested scopes in functions practicaly imo have rather no to
much big sense (imo for example fact that afair if and for loop have
its on scope is most probably an error/mistake..is and loops are so
called lightweight control structures not searate material scopes
On 5/27/2026 5:40 AM, Dan Cross wrote:[...]
Mainframes are the primary example I was thinking of. Btw, the
latest incarnation of IBM's S/360/370/390 line is called
"z/Architecture" and the z17 is the current top-of-the-line
offering from Big Blue.
Fwiw, do you remember reading A-45 from:
https://www.ibm.com/docs/en/module_1678991624569/pdf/SA22-7832-14.pdf
I read that sucker many times back in the day. PLO was pretty fun.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> writes:
On 5/27/2026 5:40 AM, Dan Cross wrote:[...]
Mainframes are the primary example I was thinking of. Btw, the
latest incarnation of IBM's S/360/370/390 line is called
"z/Architecture" and the z17 is the current top-of-the-line
offering from Big Blue.
Fwiw, do you remember reading A-45 from:
https://www.ibm.com/docs/en/module_1678991624569/pdf/SA22-7832-14.pdf
I read that sucker many times back in the day. PLO was pretty fun.
That's "z/Architecture Principles of Operation", a 2240-page PDF.
Page A-45 is "Multiprogramming and Multiprocessing Examples".
Next time you post a link like that, tell us what it is so somebody
else doesn't have to do it for you.
On Wed, 27 May 2026 15:33:46 +0200, fir wrote:
... imo nested scopes in functions practicaly imo have rather no to
much big sense (imo for example fact that afair if and for loop have
its on scope is most probably an error/mistake..is and loops are so
called lightweight control structures not searate material scopes
What?s ?lightweight? about it is that the local variables (including particularly the loop variable, if any) can mostly reside in
registers. This can mean no necessity for any special stack setup at
all, to enter and exit those constructs.
Lawrence D?Oliveiro pisze:
i mean if you look on function code body like in half assembly level
On Wed, 27 May 2026 15:33:46 +0200, fir wrote:
... imo nested scopes in functions practicaly imo have rather no
to much big sense (imo for example fact that afair if and for loop
have its on scope is most probably an error/mistake..is and loops
are so called lightweight control structures not searate material
scopes
What?s ?lightweight? about it is that the local variables
(including particularly the loop variable, if any) can mostly
reside in registers. This can mean no necessity for any special
stack setup at all, to enter and exit those constructs.
(by half assembly i mean you know that those loops and branches are
like ip (instruction pointer) jumps in function...so you may see
either those control structures/trajectories either more light in
regard to variables they use or othervise you may see they maybe
heavy an allocating/dealocating ram you can see as light in regard
to control structures (maybe)
On Thu, 28 May 2026 07:33:51 +0200, fir wrote:
Lawrence D?Oliveiro pisze:
i mean if you look on function code body like in half assembly level
On Wed, 27 May 2026 15:33:46 +0200, fir wrote:
... imo nested scopes in functions practicaly imo have rather no
to much big sense (imo for example fact that afair if and for loop
have its on scope is most probably an error/mistake..is and loops
are so called lightweight control structures not searate material
scopes
What?s ?lightweight? about it is that the local variables
(including particularly the loop variable, if any) can mostly
reside in registers. This can mean no necessity for any special
stack setup at all, to enter and exit those constructs.
(by half assembly i mean you know that those loops and branches are
like ip (instruction pointer) jumps in function...so you may see
either those control structures/trajectories either more light in
regard to variables they use or othervise you may see they maybe
heavy an allocating/dealocating ram you can see as light in regard
to control structures (maybe)
That would be an ecumenical matter.
Lawrence D?Oliveiro pisze:
On Thu, 28 May 2026 07:33:51 +0200, fir wrote:
Lawrence D?Oliveiro pisze:
i mean if you look on function code body like in half assembly level
On Wed, 27 May 2026 15:33:46 +0200, fir wrote:
... imo nested scopes in functions practicaly imo have rather no
to much big sense (imo for example fact that afair if and for loop
have its on scope is most probably an error/mistake..is and loops
are so called lightweight control structures not searate material
scopes
What?s ?lightweight? about it is that the local variables
(including particularly the loop variable, if any) can mostly
reside in registers. This can mean no necessity for any special
stack setup at all, to enter and exit those constructs.
(by half assembly i mean you know that those loops and branches are
like ip (instruction pointer) jumps in function...so you may see
either those control structures/trajectories either more light in
regard to variables they use or othervise you may see they maybe
heavy an allocating/dealocating ram you can see as light in regard
to control structures (maybe)
That would be an ecumenical matter.
i mean controll structures not necessary (or mostly not) generat its own scope imo... function makes its own scope but control structures im not
sure but maybe usually just not - i think they make opportunity to syntaxically make separate scopes but probably not 'semantically'
often this is annoying like
for(int i=0; i<tab_max;i++)
{
˙˙ int sum = 0; sum+=tab[i];
˙˙ //should be int sum+=tab[i]; but this probably not compiles
}
On 28/05/2026 16:35, fir wrote:
Lawrence D?Oliveiro pisze:
On Thu, 28 May 2026 07:33:51 +0200, fir wrote:
Lawrence D?Oliveiro pisze:
i mean if you look on function code body like in half assembly level
On Wed, 27 May 2026 15:33:46 +0200, fir wrote:
... imo nested scopes in functions practicaly imo have rather no
to much big sense (imo for example fact that afair if and for loop >>>>>> have its on scope is most probably an error/mistake..is and loops
are so called lightweight control structures not searate material
scopes
What?s ?lightweight? about it is that the local variables
(including particularly the loop variable, if any) can mostly
reside in registers. This can mean no necessity for any special
stack setup at all, to enter and exit those constructs.
(by half assembly i mean you know that those loops and branches are
like ip (instruction pointer) jumps in function...so you may see
either those control structures/trajectories either more light in
regard to variables they use or othervise you may see they maybe
heavy an allocating/dealocating ram you can see as light in regard
to control structures (maybe)
That would be an ecumenical matter.
i mean controll structures not necessary (or mostly not) generat its
own scope imo... function makes its own scope but control structures
im not sure but maybe usually just not - i think they make opportunity
to syntaxically make separate scopes but probably not 'semantically'
often this is annoying like
for(int i=0; i<tab_max;i++)
{
˙˙˙ int sum = 0; sum+=tab[i];
˙˙˙ //should be int sum+=tab[i]; but this probably not compiles
}
Try:
˙ for (int i=0, sum=0; i<tab_max; ++i) { sum += tab[i];}
Dan Cross <cross@spitfire.i.gajendra.net> wrote:
In article <10v5pn8$2guem$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/26/2026 7:23 PM, Dan Cross wrote:
In article <10v560l$2csvm$1@dont-email.me>,
Lynn McGuire <lynnmcguire5@gmail.com> wrote:
On 5/25/2026 8:46 AM, Kenny McCormack wrote:
Trigger Warning: This post contains the dreaded "s word". Viewer
discretion advised.
[snip]
What is the dreaded s word, scripting ?
I think it's "stack". The C standard doesn't make any reference
to call stacks or stack allocation, AFAIK. However, in practice
most systems use one; there are a handful of exceptions however.
I used to write assembly language on IBM 370s and Fortran on IBM 3090s.
No stack that I know of. My prof in my IBM 370 assembly language class
taught us how to create a simulated stack.
I have no idea about modern IBM mainframes. I don't even know what
their model number is.
Mainframes are the primary example I was thinking of. Btw, the
latest incarnation of IBM's S/360/370/390 line is called
"z/Architecture" and the z17 is the current top-of-the-line
offering from Big Blue.
On older version of that ISA, function (nee procedure,
subroutine, etc) calls are made by instructions that take a GP
register operand that holds the address of the next instruction;
that "link register" thus holds the function return address, and
there is a "store multiple" instruction to write one or more
registers to memory (excuse me, "storage" in IBM parlance); one
presumes that a program (or a langauge; I'm assuming assembler
here) adopts some convention for a designated link register, and
writes it into a software-managed "save area" of memory on entry
or before itself making a call. This is almost RISC-like, and
unlike (say) x86 that automatically pushes the return address
onto a hardware stack that is pointed to by a dedicated "stack
pointer" register.
At hardware level it is very similar to what ARM is doing, so
yes, RISC uses essentially the same method. Difference is in
management of "save area".
I believe traditionally, entry into a function (nee procedure,
subroutine, etc) involved allocating the temporary working space
required for that subroutine, and adding that to a linked list
of such allocations, as opposed to operating on a window into a
single, larger region.
Yes, that was general pattern. Irony of this was that general
function call needed something like 2 machine level function
calls.
Performance critical non-reentant functions freqently had dedicated
"save area".
But I see no reason a program couldn't
allocate a large region and use another register as a "stack"
pointer into that region in a more conventional way.
AFAIK this is how IBM is doing this now, using pretty conventional
stack.
If one
were feeling bold, one could even take a third register to use
as a frame pointer. Idly, I wonder if one should refer to the
more common kind of stack use as the more "conventional" way,
since this mechanism in the lizard brain of z/arch predates most
architectures in use today by a couple of decades.
That aside, poking around briefly it looks like IBM supports
"language environments" that seem roughly like runtimes and ABIs
for, well, specific languages. One presumes different languages
might do things in ways similar to other machines. I don't have
time right now to look in more detail, but I see some indicators
that this may be the case, and a few documents describing
hardware mention stacks, so perhaps they've added some support
in the 64-bit ISA.
- Dan C.
Experimenting with gcc (4.8.3, 14.2.1) shows that the
stack layout depends on -O.
int fff(int yyy, int xxx)
{
int ab = yyy + xxx;
{
int bb;
printf("%p\n", &bb);
}
{
int bc;
printf("%p\n", &bc);
}
printf("%p\n", &ab);
return 0;
}
scott@slp53.sl.home (Scott Lurndal) writes:[...]
int fff(int yyy, int xxx)
{
int ab = yyy + xxx;
{
int bb;
printf("%p\n", &bb);
}
{
int bc;
printf("%p\n", &bc);
}
printf("%p\n", &ab);
return 0;
}
This function has undefined behavior.
| Sysop: | Tetrazocine |
|---|---|
| Location: | Melbourne, VIC, Australia |
| Users: | 14 |
| Nodes: | 8 (0 / 8) |
| Uptime: | 198:19:36 |
| Calls: | 218 |
| Files: | 21,503 |
| Messages: | 82,304 |