Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #107367 > unrolled thread
| Started by | acidlategamer@gmail.com |
|---|---|
| First post | 2017-03-29 04:31 -0700 |
| Last post | 2017-03-29 11:45 -0400 |
| Articles | 12 — 7 participants |
Back to article view | Back to comp.lang.c
Const values not stored in .text section acidlategamer@gmail.com - 2017-03-29 04:31 -0700
Re: Const values not stored in .text section acidlategamer@gmail.com - 2017-03-29 04:41 -0700
Re: Const values not stored in .text section David Brown <david.brown@hesbynett.no> - 2017-03-29 15:04 +0200
Re: Const values not stored in .text section acidlategamer@gmail.com - 2017-03-29 06:14 -0700
Re: Const values not stored in .text section scott@slp53.sl.home (Scott Lurndal) - 2017-03-29 13:41 +0000
Re: Const values not stored in .text section David Brown <david.brown@hesbynett.no> - 2017-03-29 16:19 +0200
Re: Const values not stored in .text section Barry Schwarz <schwarzb@dqel.com> - 2017-03-29 08:06 -0700
Re: Const values not stored in .text section jt@toerring.de (Jens Thoms Toerring) - 2017-03-29 18:38 +0000
Re: Const values not stored in .text section "James R. Kuyper" <jameskuyper@verizon.net> - 2017-03-29 11:49 -0400
Re: Const values not stored in .text section Keith Thompson <kst-u@mib.org> - 2017-03-29 09:55 -0700
Re: Const values not stored in .text section jt@toerring.de (Jens Thoms Toerring) - 2017-03-29 13:34 +0000
Re: Const values not stored in .text section "James R. Kuyper" <jameskuyper@verizon.net> - 2017-03-29 11:45 -0400
| From | acidlategamer@gmail.com |
|---|---|
| Date | 2017-03-29 04:31 -0700 |
| Subject | Const values not stored in .text section |
| Message-ID | <391e9782-09dd-43a6-a279-e9b72d6c2cd2@googlegroups.com> |
Hi all,
I have this knowledge that any const variable declared like this
const int a;
will go to .text section i.e is read only, so we should be able to get its address.
I tried this,
#include <stdio.h>
int main()
{
const int a = 32;
int *p;
p = &a;
*p = 45;
printf("%%d p\n", a, (void *)&a);
return 0;
}
compiled gcc -O3 23.c
output : 23.c: In function ‘main’:
23.c:6:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
p = &a;
^
gamer@acid:~/practice_linux/linked_list$ ./a.out
45 0x7ffe6ce0f950
So I get a warning and an address from .text section. Am I correct.
Also the const value got changed.
#include <stdio.h>
int main()
{
const static int a = 32;
int *p;
p = &a;
*p = 45;
printf("%%d p\n", a, (void *)&a);
return 0;
}
output : segmentation fault
What difference does static made here.
I am using gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
[toc] | [next] | [standalone]
| From | acidlategamer@gmail.com |
|---|---|
| Date | 2017-03-29 04:41 -0700 |
| Message-ID | <a1519bad-304e-4788-9eb6-590c025a538f@googlegroups.com> |
| In reply to | #107367 |
On Wednesday, March 29, 2017 at 5:01:54 PM UTC+5:30, acidla...@gmail.com wrote:
> Hi all,
> I have this knowledge that any const variable declared like this
>
> const int a;
>
> will go to .text section i.e is read only, so we should be able to get its address.
> I tried this,
>
> #include <stdio.h>
> int main()
> {
> const int a = 32;
> int *p;
> p = &a;
> *p = 45;
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
> compiled gcc -O3 23.c
> output : 23.c: In function ‘main’:
> 23.c:6:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> p = &a;
> ^
> gamer@acid:~/practice_linux/linked_list$ ./a.out
> 45 0x7ffe6ce0f950
>
> So I get a warning and an address from .text section. Am I correct.
> Also the const value got changed.
>
>
> #include <stdio.h>
> int main()
> {
> const static int a = 32;
> int *p;
> p = &a;
> *p = 45;
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
>
> output : segmentation fault
>
> What difference does static made here.
> I am using gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
when const int a;
size a.out
text data bss dec hex filename
1243 560 8 1811 713 a.out
when
const static int a;
size a.out
text data bss dec hex filename
1248 560 8 1816 718 a.out
here size of text increased.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-29 15:04 +0200 |
| Message-ID | <obgb7v$5gh$1@dont-email.me> |
| In reply to | #107367 |
On 29/03/17 13:31, acidlategamer@gmail.com wrote:
> Hi all,
> I have this knowledge that any const variable declared like this
>
> const int a;
>
> will go to .text section i.e is read only, so we should be able to get its address.
You have jumbled up a variety of concepts here.
Inside a function, this declares a local "int" variable and tells the
compiler that you promise not to change it. Whether the compiler
generates an actual memory local for it or not, is implementation
dependent. And the compiler can legally place it in a variety of
places. A good many local "const" variables never end up in memory at
all - they are optimised away, or they stay in registers. But taking
the address of the variable usually means it will be allocated a space
in memory.
The compiler will usually put it on the stack in a function like your
first one. It is allowed to put it at a static location (such as in the
".text" section, or a ".rodata", ".const"., etc. section) if it knows
all uses of the address of the constant, and knows this is safe - noting
that if a function is called in a re-entrant manner then there will be
at least two separate "const int a" objects which must have different
addresses.
The easiest thing for the compiler, therefore, is to put this "a" on the
stack.
> I tried this,
>
> #include <stdio.h>
> int main()
> {
> const int a = 32;
> int *p;
> p = &a;
> *p = 45;
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
> compiled gcc -O3 23.c
> output : 23.c: In function ‘main’:
> 23.c:6:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> p = &a;
> ^
You promised the compiler that you would not change "a", then you took a
non-const pointer to it which would allow you to change it. The
compiler helpfully warns you about this bad practice.
> gamer@acid:~/practice_linux/linked_list$ ./a.out
> 45 0x7ffe6ce0f950
>
> So I get a warning and an address from .text section. Am I correct.
> Also the const value got changed.
The address was never in ".text" - "a" would be on the stack.
And the compiler is free to print 32 instead of 45 as the value - or
even 42, or do anything else it fancies since you lied to it.
Typically, if you enable compiler optimisation you will get 32.
>
>
> #include <stdio.h>
> int main()
> {
> const static int a = 32;
> int *p;
> p = &a;
> *p = 45;
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
>
> output : segmentation fault
>
> What difference does static made here.
> I am using gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
>
By making "a" static, you are telling the compiler that only one of
these exists in the program. Thus the compiler can allocate a single
address for it rather than putting it on the stack. And since it is
"const", the compiler will put it in a read-only memory area (".rodata"
for gcc). When you try to change memory that is protected from writing,
you get a hard fault from the cpu.
[toc] | [prev] | [next] | [standalone]
| From | acidlategamer@gmail.com |
|---|---|
| Date | 2017-03-29 06:14 -0700 |
| Message-ID | <69dbb499-1893-464b-8d25-7193e1796285@googlegroups.com> |
| In reply to | #107378 |
On Wednesday, March 29, 2017 at 6:34:56 PM UTC+5:30, David Brown wrote:
> On 29/03/17 13:31, acidlategamer@gmail.com wrote:
> > Hi all,
> > I have this knowledge that any const variable declared like this
> >
> > const int a;
> >
> > will go to .text section i.e is read only, so we should be able to get its address.
>
> You have jumbled up a variety of concepts here.
>
> Inside a function, this declares a local "int" variable and tells the
> compiler that you promise not to change it. Whether the compiler
> generates an actual memory local for it or not, is implementation
> dependent. And the compiler can legally place it in a variety of
> places. A good many local "const" variables never end up in memory at
> all - they are optimised away, or they stay in registers. But taking
> the address of the variable usually means it will be allocated a space
> in memory.
>
> The compiler will usually put it on the stack in a function like your
> first one. It is allowed to put it at a static location (such as in the
> ".text" section, or a ".rodata", ".const"., etc. section) if it knows
> all uses of the address of the constant, and knows this is safe - noting
> that if a function is called in a re-entrant manner then there will be
> at least two separate "const int a" objects which must have different
> addresses.
>
> The easiest thing for the compiler, therefore, is to put this "a" on the
> stack.
>
> > I tried this,
> >
> > #include <stdio.h>
> > int main()
> > {
> > const int a = 32;
> > int *p;
> > p = &a;
> > *p = 45;
> > printf("%%d p\n", a, (void *)&a);
> > return 0;
> > }
> > compiled gcc -O3 23.c
> > output : 23.c: In function ‘main’:
> > 23.c:6:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> > p = &a;
> > ^
>
> You promised the compiler that you would not change "a", then you took a
> non-const pointer to it which would allow you to change it. The
> compiler helpfully warns you about this bad practice.
>
> > gamer@acid:~/practice_linux/linked_list$ ./a.out
> > 45 0x7ffe6ce0f950
> >
> > So I get a warning and an address from .text section. Am I correct.
> > Also the const value got changed.
>
> The address was never in ".text" - "a" would be on the stack.
>
> And the compiler is free to print 32 instead of 45 as the value - or
> even 42, or do anything else it fancies since you lied to it.
> Typically, if you enable compiler optimisation you will get 32.
>
> >
> >
> > #include <stdio.h>
> > int main()
> > {
> > const static int a = 32;
> > int *p;
> > p = &a;
> > *p = 45;
> > printf("%%d p\n", a, (void *)&a);
> > return 0;
> > }
> >
> > output : segmentation fault
> >
> > What difference does static made here.
> > I am using gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
> >
>
> By making "a" static, you are telling the compiler that only one of
> these exists in the program. Thus the compiler can allocate a single
> address for it rather than putting it on the stack. And since it is
> "const", the compiler will put it in a read-only memory area (".rodata"
> for gcc). When you try to change memory that is protected from writing,
> you get a hard fault from the cpu.
I made this change
#include <stdio.h>
const int a = 32;
int main()
{
int *p;
p = &a;
*p = 45;
printf("%d %p\n", a, (void *)&a);
return 0;
}
output : segmentation fault
What happens in this case? Now where should be the variable stored now?
So I deduce this in my compiler case
1. If a variable is const and is a global value, then it will be stored on text section.
2. If a variable is a const and a local variable, compiler will do what it think is best place to store.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-03-29 13:41 +0000 |
| Message-ID | <7QOCA.259405$IM7.42933@fx39.iad> |
| In reply to | #107380 |
acidlategamer@gmail.com writes:
>On Wednesday, March 29, 2017 at 6:34:56 PM UTC+5:30, David Brown wrote:
>> > #include <stdio.h>
>> > int main()
>> > {
>> > const static int a =3D 32;
>> > int *p;
>> > p =3D &a;
>> > *p =3D 45;
>> > printf("%%d p\n", a, (void *)&a);
>> > return 0;
>> > }
>> >=20
>> > output : segmentation fault
The linker locates 'a' in a read-only page of
memory. You get a SIGSEGV when you attempt
to modify the value.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-03-29 16:19 +0200 |
| Message-ID | <obgfje$k1k$1@dont-email.me> |
| In reply to | #107380 |
On 29/03/17 15:14, acidlategamer@gmail.com wrote:
/Please/ get a proper newsreader and newserver account. Google groups
posts screw up line breaks badly. Make it easier for people to help
you, then you get more help.
> I made this change
>
> #include <stdio.h>
> const int a = 32;
> int main()
> {
>
> int *p;
> p = &a;
> *p = 45;
> printf("%d %p\n", a, (void *)&a);
> return 0;
> }
>
> output : segmentation fault
>
> What happens in this case? Now where should be the variable stored now?
It will be put in a statically allocated area of memory, probably a
read-only section. (Since you get a segmentation fault, that appears to
be the case.)
> So I deduce this in my compiler case
>
> 1. If a variable is const and is a global value, then it will be
> stored on text section.
How do you deduce that? Did you read what I wrote in my first reply?
Did you use objdump or other tools to /look/ at the sections? gcc will
put it in ".rodata" by default, along with any other data that is
read-only but not executable code. ".text" is primarily for executable
code (the names of these sections are historical rather than strictly
descriptive).
>
> 2. If a variable is a const and a local variable, compiler will do
> what it think is best place to store.
>
How do you deduce that? Again, read what I wrote last time. If you
don't take the address of the variable, the compiler has a lot of
freedom about where to place it (if anywhere). If you take its address,
it will typically be forced to put it on the stack.
But the real lesson to be learned here is to pay attention to the
compiler warnings (preferably using -Wall, perhaps also -Wextra and
-pedantic) and stop writing code that breaks the rules of C. Don't
write to "const" objects.
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-03-29 08:06 -0700 |
| Message-ID | <juindc1481gnf8dg0m86clne76sqsfr90p@4ax.com> |
| In reply to | #107380 |
On Wed, 29 Mar 2017 06:14:50 -0700 (PDT), acidlategamer@gmail.com
wrote:
>I made this change
>
>#include <stdio.h>
>const int a = 32;
>int main()
>{
>
>int *p;
>p = &a;
Did your compiler generate a diagnostic for this statement? If not,
maybe you should increase the level. You are assigning the address of
a const qualified object to a pointer not so qualified.
>*p = 45;
>printf("%d %p\n", a, (void *)&a);
>return 0;
>}
>
>output : segmentation fault
You should not attempt to execute programs which do not compile
cleanly.
>What happens in this case? Now where should be the variable stored now?
>So I deduce this in my compiler case
>
>1. If a variable is const and is a global value, then it will be stored on text section.
>
>2. If a variable is a const and a local variable, compiler will do what it think is best place to store.
All of which begs the question - why do you care? Delving deep into
system specific details is of value mostly for compiler writers and
the rare application programmer who truly needs to perform extreme
optimization.
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2017-03-29 18:38 +0000 |
| Message-ID | <ek2d95Fecr4U1@mid.uni-berlin.de> |
| In reply to | #107394 |
Barry Schwarz <schwarzb@dqel.com> wrote:
> All of which begs the question - why do you care? Delving deep into
> system specific details is of value mostly for compiler writers and
> the rare application programmer who truly needs to perform extreme
> optimization.
I'd also consider curiosity a very good reason;-) The
important point, though, is not to merely learn by try-
and-error, otherwise it's all too simple to come to
very wrong conclusions.
Best regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-03-29 11:49 -0400 |
| Message-ID | <4cdd12d1-c0a3-a4f0-83e9-bc630d8d928f@verizon.net> |
| In reply to | #107380 |
On 03/29/2017 09:14 AM, acidlategamer@gmail.com wrote:
...
> I made this change
>
> #include <stdio.h>
> const int a = 32;
> int main()
> {
>
> int *p;
> p = &a;
> *p = 45;
> printf("%d %p\n", a, (void *)&a);
> return 0;
> }
>
> output : segmentation fault
>
> What happens in this case? Now where should be the variable stored now?
Since you've not removed either of the two reasons why your code has
undefined behavior, there's no particular place that the variable
"should" be stored. It need not be stored at all, and if it is, it could
be stored on the back of your head.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-03-29 09:55 -0700 |
| Message-ID | <lnk2783tvm.fsf@kst-u.example.com> |
| In reply to | #107380 |
acidlategamer@gmail.com writes:
[...]
> I made this change
I've taken the liberty of fixing your code's indentation.
> #include <stdio.h>
> const int a = 32;
This defines an object named "a". It has type int, and its initial
value is 32. It has static storage duration, meaning that it exists
for the entire lifetime of the program. The "const" means that any
attempt to assign to it directly is a constraint violation, and any
attempt to modify its value indirectly has undefined behavior.
> int main()
A very minor point: this should be "int main(void)".
> {
> int *p;
> p = &a;
&a is of type "const int*". p is of type "int*". Assigning an int*
value to a const int* object is a constraint violation.
You probably got a non-fatal warning, but your compiler could have
treated it as a fatal error (and if you had compiled with "gcc
-pedantic-errors", it would have).
Saying that something is a "constraint violation" is about as close as C
comes to saying that something is illegal.
So don't do that.
> *p = 45;
If the compiler hasn't already rejected your program, this has undefined
behavior, because you're trying to modify a const-qualified object.
> printf("%d %p\n", a, (void *)&a);
> return 0;
> }
> output : segmentation fault
>
> What happens in this case? Now where should be the variable stored now?
> So I deduce this in my compiler case
It doesn't really where it's stored. The C standard says nothing about
text sections. It specifies the lifetime of storage.
> 1. If a variable is const and is a global value, then it will be
> stored on text section.
Any object defined at file scope (outside any function definition) *or*
with the "static" keyword has static storage duration, meaning that it
exists (at least logically) during the entire execution of the program.
The "const" keyword doesn't affect this, it merely means that you can't
legally modify it.
> 2. If a variable is a const and a local variable, compiler will do
> what it think is best place to store.
An object defined within a function definition without the "static"
keyword has automatic storage duration, meaning that it exists (is
created and then deallocated) only during the execution of the enclosing
block. Again, the "const" keyword doesn't affect this.
Compilers can and often do perform optimizations that change how and
whether objects are stored. For example, if you write
const int n = 42;
at block scope, and never take the address of n, then a compiler might
choose not to allocate storage for n, and to replace every reference to
n with a constant value of 42. It can do the same thing without the
"const" if it can prove that n is never modified.
As for "global" objects, things like the "text segment" and "bss
segment" are implementation details, not mentioned by the language
standard. You can probably find out how particular objects are stored
by examining an assembly listing, and that might be affected by the
presence of absence of "const" and/or an initialization. But don't
assume that any such information applies beyond the particular
implementation you're using.
--
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 | jt@toerring.de (Jens Thoms Toerring) |
|---|---|
| Date | 2017-03-29 13:34 +0000 |
| Message-ID | <ek1reoFabkiU1@mid.uni-berlin.de> |
| In reply to | #107367 |
acidlategamer@gmail.com wrote:
> I have this knowledge that any const variable declared like this
> const int a;
> will go to .text section i.e is read only, so we should be able to get its address.
Wrong assumption. First of all, all of this is an implementation
detail, nothing in the C standard requires the existence of a
.text segment (nor what we usually think of as a stack or heap).
Thus any observations you make on one machine, compiler and
operating system can't expected to necessarily also be valid
for a different machine, compiler or OS.
That out of the way (so the rest is a bit off-topic), compilers
often stick global and static variables into .data and .text (or
.rodata) segments, the former for modifiable data, the second
for const static and global variables (if the system supports
such a distinction)
Compilers typically don't put variables defined local to a
function (but not qualified as static) into the .data or
.text segment, but usually on the stack, const qualified
or not.
The result of this is the behaviour of your "experimental" pro-
grams, but the stack is writable, so no further consequemces.
In the first case 'a' is on the stack, the compiler warns you
about that. In the second case the compiler should warn you
about it too, 'a' is placed in the .text segment and a write
access results in a segmentation fault. Not untypical when you
do something you're supposed not to do - depending on circum-
stances it may seem to work anyway or something else happens.
The question of whether you can take the address of a variable
also has nothing to do with them being const. If you take the
address of a variable it most likely will prevent the compiler
from "optimizing out" the variable. If you wouldn't take the
address of 'a' in your programs the compiler might recognize
that the value can be used directly and thus it may simply drop
the definition, not using any memory for it, and replace any
use of 'a' by its value.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-03-29 11:45 -0400 |
| Message-ID | <13ff7fee-c428-e0ef-d604-baa8de8a0b8d@verizon.net> |
| In reply to | #107367 |
On 03/29/2017 07:31 AM, acidlategamer@gmail.com wrote:
> Hi all,
> I have this knowledge that any const variable declared like this
>
> const int a;
>
> will go to .text section i.e is read only, so we should be able to get its address.
That "knowledge" is implementation-specific. Whether or not an
implementation even has such a thing as "sections" will vary from one
platform to another - even implementations that use named sections need
not use the same names, or for the same purpose.
> I tried this,
>
> #include <stdio.h>
> int main()
> {
> const int a = 32;
> int *p;
> p = &a;
That is a constraint violation. When assigning to a pointer object, "the
type pointed to by the left has all the qualifiers of the type pointed
to by the right" (6.5.16.1p1). The type that &a points at has a
qualifier (const) that the type pointed at by p does not. A diagnostic
message is mandatory. Producing an executable is optional. If an
implementation should choose to produce such an executable, and if you
should choose to try to execute it, the behavior is undefined.
The purpose of this constraint is to protect you from accidentally
trying to change something that has been marked as something that should
NOT be changed.
You can get cover up this problem (without actually removing it) with a
cast: (int *)&a.
> *p = 45;
p points at a. a has been defined as 'const'. Even if you cover up the
previous problem with a cast, this code still has undefined behavior:
"If an attempt is made to modify an object defined with a const
qualified type through use of an lvalue with non-const-qualified type,
the behavior is undefined." (6.7.3p6)
When the behavior is undefined, that means that the standard imposes no
requirements on the behavior of the resulting program. In particular, it
is allowed to produce exactly the behavior you incorrectly thought it
was required to produce. It could also make your computer start playing
"La Macarena".
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
> compiled gcc -O3 23.c
> output : 23.c: In function ‘main’:
> 23.c:6:3: warning: assignment discards ‘const’ qualifier from pointer target type [enabled by default]
> p = &a;
> ^
> gamer@acid:~/practice_linux/linked_list$ ./a.out
> 45 0x7ffe6ce0f950
>
> So I get a warning and an address from .text section. Am I correct.
You're correct about getting a warning. As a block-scope variable
associated with main(), 'a' is likely to have been allocated from the
stack. However, since the behavior is undefined, in principle that
address is completely meaningless.
> Also the const value got changed.
Since the behavior is undefined, that's one of the permitted possibilities
> #include <stdio.h>
> int main()
> {
> const static int a = 32;
> int *p;
> p = &a;
> *p = 45;
> printf("%%d p\n", a, (void *)&a);
> return 0;
> }
>
> output : segmentation fault
>
> What difference does static made here.
This program has precisely the same problems as the previous one.
However, since 'a' has been declared static, it could have been
allocated in a different piece of memory. That's apparently a read-only
block of memory, which would be reasonable for an object defined as
'const', hence the seg-fault. This is one of the many possibilities
allowed when the behavior of your code is undefined.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web