Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #391294 > unrolled thread
| Started by | bart <bc@freeuk.com> |
|---|---|
| First post | 2025-03-17 23:51 +0000 |
| Last post | 2025-03-21 00:33 +0000 |
| Articles | 20 on this page of 62 — 13 participants |
Back to article view | Back to comp.lang.c
Bart's Language bart <bc@freeuk.com> - 2025-03-17 23:51 +0000
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-18 12:17 +0000
Re: Bart's Language bart <bc@freeuk.com> - 2025-03-18 13:54 +0000
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-18 15:10 +0000
Re: Bart's Language bart <bc@freeuk.com> - 2025-03-18 15:45 +0000
Re: Bart's Language David Brown <david.brown@hesbynett.no> - 2025-03-18 17:31 +0100
int a = a (Was: Bart's Language) gazelle@shell.xmission.com (Kenny McCormack) - 2025-03-18 18:04 +0000
Re: int a = a (Was: Bart's Language) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-03-18 19:36 +0100
Re: int a = a (Was: Bart's Language) Kaz Kylheku <643-408-1753@kylheku.com> - 2025-03-18 19:11 +0000
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-19 15:56 +0100
Re: int a = a (Was: Bart's Language) scott@slp53.sl.home (Scott Lurndal) - 2025-03-19 16:38 +0000
Re: int a = a (Was: Bart's Language) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2025-03-19 14:29 -0700
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-20 09:39 +0100
Re: int a = a (Was: Bart's Language) bart <bc@freeuk.com> - 2025-03-20 11:59 +0000
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-20 15:46 +0100
Re: int a = a (Was: Bart's Language) wij <wyniijj5@gmail.com> - 2025-03-20 23:13 +0800
Re: int a = a (Was: Bart's Language) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-20 02:02 -0700
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-20 15:57 +0100
Re: int a = a (Was: Bart's Language) Kaz Kylheku <643-408-1753@kylheku.com> - 2025-03-19 17:07 +0000
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-19 13:34 -0700
Re: int a = a Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-20 02:54 -0700
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-20 03:20 -0700
Re: int a = a David Brown <david.brown@hesbynett.no> - 2025-03-20 16:22 +0100
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-20 12:46 -0700
Re: int a = a David Brown <david.brown@hesbynett.no> - 2025-03-21 10:44 +0100
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-21 12:23 -0700
Re: int a = a David Brown <david.brown@hesbynett.no> - 2025-03-21 21:46 +0100
Re: int a = a Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-22 13:59 -0700
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-22 15:37 -0700
Re: int a = a Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-04-28 09:39 -0700
Re: int a = a Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-04-29 13:12 -0700
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-04-29 13:34 -0700
Re: int a = a David Brown <david.brown@hesbynett.no> - 2025-03-20 15:42 +0100
Re: int a = a (Was: Bart's Language) scott@slp53.sl.home (Scott Lurndal) - 2025-03-18 19:37 +0000
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-18 20:51 +0100
Re: int a = a (Was: Bart's Language) Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-03-18 23:27 +0100
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-19 11:40 +0100
Re: int a = a (Was: Bart's Language) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-18 23:52 -0700
Re: int a = a Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-19 01:55 -0700
Re: int a = a Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-04-27 13:41 -0700
Re: int a = a (Was: Bart's Language) David Brown <david.brown@hesbynett.no> - 2025-03-19 11:43 +0100
Re: int a = a (Was: Bart's Language) Rosario19 <Ros@invalid.invalid> - 2025-03-19 13:23 +0100
Re: int a = a (Was: Bart's Language) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-20 01:32 -0700
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-20 22:55 +0000
Re: Bart's Language Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-03-20 16:22 -0700
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-22 14:37 +0000
Re: Bart's Language James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-03-22 11:41 -0400
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-22 16:52 +0000
Re: Bart's Language James Kuyper <jameskuyper@alumni.caltech.edu> - 2025-03-22 20:12 -0400
By definition... (Was: Bart's Language) gazelle@shell.xmission.com (Kenny McCormack) - 2025-03-23 17:20 +0000
Re: Bart's Language Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-04-27 11:53 -0700
Re: Bart's Language Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2025-04-27 14:29 -0700
Re: Bart's Language Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-01-06 14:04 -0800
Re: Bart's Language Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2026-01-06 17:12 -0800
Re: Bart's Language Tim Rentsch <tr.17687@z991.linuxsc.com> - 2026-03-06 09:04 -0800
Re: Bart's Language bart <bc@freeuk.com> - 2025-03-18 22:19 +0000
Re: Bart's Language antispam@fricas.org (Waldek Hebisch) - 2025-03-20 22:38 +0000
Re: Bart's Language Kaz Kylheku <643-408-1753@kylheku.com> - 2025-03-20 23:45 +0000
Re: Bart's Language bart <bc@freeuk.com> - 2025-03-21 00:56 +0000
Re: Bart's Language Kaz Kylheku <643-408-1753@kylheku.com> - 2025-03-21 17:47 +0000
Re: Bart's Language Tim Rentsch <tr.17687@z991.linuxsc.com> - 2025-03-22 07:12 -0700
Re: Bart's Language bart <bc@freeuk.com> - 2025-03-21 00:33 +0000
Page 1 of 4 [1] 2 3 4 Next page →
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-03-17 23:51 +0000 |
| Subject | Bart's Language |
| Message-ID | <vracit$178ka$1@dont-email.me> |
On 06/03/2025 21:45, Tim Rentsch wrote: > If you post some links where I can download a current user > manual and a current compiler or interpreter, I will gladly > withdraw my comment. > Otherwise, I stand by my comment, and see no reason to > consider your alleged environment as anything other than > fiction-ware. > The point of my question is not to determine if something exists but > to find out what the purported language is. I'm tired of hearing > bart brag about his personal programming language but never giving > the specifics of what the language syntax and semantics are. It's > like listening to a used car salesman who won't let you see the > actual car. > I'm not interested in the tools. What I am asking to see is > the language. Bart: > I'm working on a document that summaries the features. ... > But, together with example programs, there should be enough info for > someone, already familiar with C, to play with it, given a suitable > implementation Or to understand some programs in it. This is the document I produced: https://github.com/sal55/langs/blob/master/MFeatures.md A couple of more substantial demo programs are here: https://github.com/sal55/langs/tree/master/MExamples (The bignum.m file was ported - by hand - to the bignum.c version that I posted recently.) I haven't provided an implementation, which would be a 400KB binary 'mm.exe' that runs on Windows. I can do that if somebody wants and they can figure out how to get it past their AV. (There are other ways but they start to get complicated. A version for Linux, for an older language spec, that relies on a C backend, supplied as a C source file, is also a possibility, but that is getting beyond what I'm prepared to do. I've anyway done it all before.) I realise that this is not exactly on topic in a C forum, but a couple of people have been curious about this. I also didn't see any difference between a post in that thread, or a new one.
[toc] | [next] | [standalone]
| From | antispam@fricas.org (Waldek Hebisch) |
|---|---|
| Date | 2025-03-18 12:17 +0000 |
| Message-ID | <vrbo88$1j3e0$1@paganini.bofh.team> |
| In reply to | #391294 |
bart <bc@freeuk.com> wrote:
>
> This is the document I produced:
>
> https://github.com/sal55/langs/blob/master/MFeatures.md
>
> A couple of more substantial demo programs are here:
> https://github.com/sal55/langs/tree/master/MExamples
>
> (The bignum.m file was ported - by hand - to the bignum.c version that I
> posted recently.)
Looking at features, can you say if the program below works?
And if it works, what is retrun value of foo? "Equvalent" can
be written in C, but in C you have to keep sane order.
proc baz =
println "Line 4"
end
func c3(int x) int =
println "Line 1"
x
end
func foo() int =
const a = b + c3(c)
bar
const b = c + c2(2)
baz
const c = c1(10)
end
func c2(int x) int =
println "Line 3"
x
end
proc bar =
println "Line 2"
end
func c1(int x) int =
println "Line 5"
x
--
Waldek Hebisch
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-03-18 13:54 +0000 |
| Message-ID | <vrbtve$2irc9$1@dont-email.me> |
| In reply to | #391299 |
On 18/03/2025 12:17, Waldek Hebisch wrote:
> bart <bc@freeuk.com> wrote:
>>
>> This is the document I produced:
>>
>> https://github.com/sal55/langs/blob/master/MFeatures.md
>>
>> A couple of more substantial demo programs are here:
>> https://github.com/sal55/langs/tree/master/MExamples
>>
>> (The bignum.m file was ported - by hand - to the bignum.c version that I
>> posted recently.)
>
> Looking at features, can you say if the program below works?
> And if it works, what is retrun value of foo? "Equvalent" can
> be written in C, but in C you have to keep sane order.
There were some tweaks needed; it indicates some basic info missing from
my write-up! (For example, that the function call needs to be bar() not
bar; 'const' is only for compile-time expressions; and that C's 'const'
doesn't exist - it only briefly mentions an attempt at 'let'.)
The revised code is shown below, with what I assumed were your
intentions. And below that is that code ported to C. Both versions
produce this output:
Line 1
Line 2
Line 3
Line 4
Line 5
10
Line 1
Line 2
Line 3
Line 4
Line 5
10
Note that both 'b' and 'c' in foo() are used uninitialised. I couldn't
apply 'const' to those, as the const declaration would be separate from
the assignment, and the later assignment is then not possible.
(To answer your presumably implied point, in:
print a
int a:=100
the assignment is done at that place in the code (after print), but the
scope of 'a' is function-wide. My compiler doesn't detect accesses to
unitialised variables, but I could add a debug option to clear
stack-frame variables on function entry.)
--------------------------
proc baz =
println "Line 4"
end
func c3(int x) int =
println "Line 1"
x
end
func foo() int =
int a := b + c3(c)
bar()
int b := c + c2(2)
baz()
int c := c1(10)
end
func c2(int x) int =
println "Line 3"
x
end
proc bar =
println "Line 2"
end
func c1(int x) int =
println "Line 5"
x
end
proc main =
println foo()
println foo()
end
--------------------------
#include <stdio.h>
void baz();
int c3(int);
int c2(int);
void bar();
int c1(int);
void baz() {
puts("Line 4");
}
int c3(int x) {
puts("Line 1");
return x;
}
int foo() {
int b, c;
const int a = b+c3(c);
bar();
b = c + c2(2);
baz();
return (c = c1(10));
}
int c2(int x) {
puts("Line 3");
return x;
}
void bar() {
puts("Line 2");
}
int c1(int x) {
puts("Line 5");
return x;
}
int main(void) {
printf("%d\n", foo());
printf("%d\n", foo());
}
--------------------------
[toc] | [prev] | [next] | [standalone]
| From | antispam@fricas.org (Waldek Hebisch) |
|---|---|
| Date | 2025-03-18 15:10 +0000 |
| Message-ID | <vrc2d5$1jjrf$1@paganini.bofh.team> |
| In reply to | #391301 |
bart <bc@freeuk.com> wrote:
> On 18/03/2025 12:17, Waldek Hebisch wrote:
>> bart <bc@freeuk.com> wrote:
>>>
>>> This is the document I produced:
>>>
>>> https://github.com/sal55/langs/blob/master/MFeatures.md
>>>
>>> A couple of more substantial demo programs are here:
>>> https://github.com/sal55/langs/tree/master/MExamples
>>>
>>> (The bignum.m file was ported - by hand - to the bignum.c version that I
>>> posted recently.)
>>
>> Looking at features, can you say if the program below works?
>> And if it works, what is retrun value of foo? "Equvalent" can
>> be written in C, but in C you have to keep sane order.
>
>
> There were some tweaks needed; it indicates some basic info missing from
> my write-up! (For example, that the function call needs to be bar() not
> bar; 'const' is only for compile-time expressions; and that C's 'const'
> doesn't exist - it only briefly mentions an attempt at 'let'.)
>
> The revised code is shown below, with what I assumed were your
> intentions.
Well, my intentions beter correspond to the C version below:
int foo() {
const int c = c1(10);
const int b = c + c2(2);
const int a = b+c3(c);
bar();
baz();
return c;
}
Part of the question was if "execution" of declarations is
interleaved with execution of code or if declarations go
before the code.
I am not saying that you should implement this, rejecting the
code as insane would be fine for me.
> And below that is that code ported to C. Both versions
> produce this output:
>
> Line 1
> Line 2
> Line 3
> Line 4
> Line 5
> 10
> Line 1
> Line 2
> Line 3
> Line 4
> Line 5
> 10
>
> Note that both 'b' and 'c' in foo() are used uninitialised. I couldn't
> apply 'const' to those, as the const declaration would be separate from
> the assignment, and the later assignment is then not possible.
>
> (To answer your presumably implied point, in:
>
> print a
> int a:=100
>
> the assignment is done at that place in the code (after print), but the
> scope of 'a' is function-wide. My compiler doesn't detect accesses to
> unitialised variables, but I could add a debug option to clear
> stack-frame variables on function entry.)
I see. So your feature conflicts with C feature "variable which is
initialized at declaration time is always used initialized".
--
Waldek Hebisch
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-03-18 15:45 +0000 |
| Message-ID | <vrc4eb$2p28t$1@dont-email.me> |
| In reply to | #391304 |
On 18/03/2025 15:10, Waldek Hebisch wrote:
> bart <bc@freeuk.com> wrote:
>> On 18/03/2025 12:17, Waldek Hebisch wrote:
>> There were some tweaks needed; it indicates some basic info missing from
>> my write-up! (For example, that the function call needs to be bar() not
>> bar; 'const' is only for compile-time expressions; and that C's 'const'
>> doesn't exist - it only briefly mentions an attempt at 'let'.)
>>
>> The revised code is shown below, with what I assumed were your
>> intentions.
>
> Well, my intentions beter correspond to the C version below:
>
> int foo() {
> const int c = c1(10);
> const int b = c + c2(2);
> const int a = b+c3(c);
> bar();
> baz();
> return c;
> }
>
> Part of the question was if "execution" of declarations is
> interleaved with execution of code or if declarations go
> before the code.
A declaration like:
int a := x
can be considered to be:
int a; a := x
where the declaration can go anywhere in the scope=, but the assignment
must be done here. There are languages where you have:
print x
where x is ...
But the typical usage pattern in my own programs is that local variable
are declared before first use.
(Maybe a compiler option can enforce that, but I don't see it as critical.)
>> print a
>> int a:=100
>>
>> the assignment is done at that place in the code (after print), but the
>> scope of 'a' is function-wide. My compiler doesn't detect accesses to
>> unitialised variables, but I could add a debug option to clear
>> stack-frame variables on function entry.)
>
> I see. So your feature conflicts with C feature "variable which is
> initialized at declaration time is always used initialized".
That doesn't happen here:
int a = a;
gcc (with no extra options) tcc and bcc both put some undefined value in a.
gcc won't warn until you say '-Wextra', and then only for:
int a = a + 1;
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-03-18 17:31 +0100 |
| Message-ID | <vrc75b$2r4lt$1@dont-email.me> |
| In reply to | #391305 |
On 18/03/2025 16:45, bart wrote:
> On 18/03/2025 15:10, Waldek Hebisch wrote:
>> bart <bc@freeuk.com> wrote:
>>> On 18/03/2025 12:17, Waldek Hebisch wrote:
>
>>> There were some tweaks needed; it indicates some basic info missing from
>>> my write-up! (For example, that the function call needs to be bar() not
>>> bar; 'const' is only for compile-time expressions; and that C's 'const'
>>> doesn't exist - it only briefly mentions an attempt at 'let'.)
>>>
>>> The revised code is shown below, with what I assumed were your
>>> intentions.
>>
>> Well, my intentions beter correspond to the C version below:
>>
>> int foo() {
>> const int c = c1(10);
>> const int b = c + c2(2);
>> const int a = b+c3(c);
>> bar();
>> baz();
>> return c;
>> }
>>
>> Part of the question was if "execution" of declarations is
>> interleaved with execution of code or if declarations go
>> before the code.
>
> A declaration like:
>
> int a := x
>
> can be considered to be:
>
> int a; a := x
>
> where the declaration can go anywhere in the scope=, but the assignment
> must be done here. There are languages where you have:
>
> print x
> where x is ...
>
> But the typical usage pattern in my own programs is that local variable
> are declared before first use.
>
> (Maybe a compiler option can enforce that, but I don't see it as critical.)
>
>>> print a
>>> int a:=100
>>>
>>> the assignment is done at that place in the code (after print), but the
>>> scope of 'a' is function-wide. My compiler doesn't detect accesses to
>>> unitialised variables, but I could add a debug option to clear
>>> stack-frame variables on function entry.)
>>
>> I see. So your feature conflicts with C feature "variable which is
>> initialized at declaration time is always used initialized".
>
> That doesn't happen here:
>
> int a = a;
>
> gcc (with no extra options) tcc and bcc both put some undefined value in a.
It would be a little more accurate (in C terminology) to call it an
"unspecified value" rather than an "undefined value" - gcc, and many
other compilers, treat that as meaning "a" gets a valid int value, but
you don't care which value it is. Using the value in "a" is allowed -
i.e., it is not considered as undefined behaviour by the compiler. (I
am not sure if the C standards require "int a = a;" to be treated like
that - I suspect that it is undefined behaviour from the standards
viewpoint, but defined by the implementation.)
>
> gcc won't warn until you say '-Wextra', and then only for:
>
> int a = a + 1;
People would not normally write "int a = a;". It is used as a common
idiom meaning "I know it is not clear to the compiler that the variable
is always initialised before use, but /I/ know it is - so disable the
use-without-initialisation warnings for this variable". So it makes
perfect sense for the compiler not to warn about it!
gcc does have a "-Winit-self" warning (not part of -Wall or -Wextra)
that will warn on "int a = a;". (It is enabled by -Wall in C++,
however, since in C++ such code can have very different semantics for
more advanced types.)
"int a = a + 1;", on the other hand, clearly attempts to read the value
of "a" before it is initialised, and a warning is issued if
"-Wuninitialized" is enabled. This warning is part of "-Wall".
[toc] | [prev] | [next] | [standalone]
| From | gazelle@shell.xmission.com (Kenny McCormack) |
|---|---|
| Date | 2025-03-18 18:04 +0000 |
| Subject | int a = a (Was: Bart's Language) |
| Message-ID | <vrccjb$b3m6$1@news.xmission.com> |
| In reply to | #391307 |
In article <vrc75b$2r4lt$1@dont-email.me>,
David Brown <david.brown@hesbynett.no> wrote:
...
>> gcc won't warn until you say '-Wextra', and then only for:
> >
> > int a = a + 1;
>
>People would not normally write "int a = a;". It is used as a common
>idiom meaning "I know it is not clear to the compiler that the variable
>is always initialised before use, but /I/ know it is - so disable the
>use-without-initialisation warnings for this variable". So it makes
>perfect sense for the compiler not to warn about it!
Wouldn't it just be easier and clearer to write: int a = 0;
and be done with it?
>"int a = a + 1;", on the other hand, clearly attempts to read the value
>of "a" before it is initialised, and a warning is issued if
>"-Wuninitialized" is enabled. This warning is part of "-Wall".
How is: int a = a + 1;
conceptually different from: int a = a;
Both are expressions involving 'a'.
Isn't 'a' being used un-initialised in both cases?
(You have to know the value of 'a' in order to evaluate the expression: a)
--
"If our country is going broke, let it be from feeding the poor and caring for
the elderly. And not from pampering the rich and fighting wars for them."
--Living Blue in a Red State--
[toc] | [prev] | [next] | [standalone]
| From | Janis Papanagnou <janis_papanagnou+ng@hotmail.com> |
|---|---|
| Date | 2025-03-18 19:36 +0100 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrcef2$33076$1@dont-email.me> |
| In reply to | #391310 |
On 18.03.2025 19:04, Kenny McCormack wrote:
> In article <vrc75b$2r4lt$1@dont-email.me>,
> David Brown <david.brown@hesbynett.no> wrote:
> ...
>>> gcc won't warn until you say '-Wextra', and then only for:
>>>
>>> int a = a + 1;
>>
>> People would not normally write "int a = a;". It is used as a common
>> idiom meaning "I know it is not clear to the compiler that the variable
>> is always initialised before use, but /I/ know it is - so disable the
>> use-without-initialisation warnings for this variable".
Wow! - It would never have occurred to me that "int a = a;" being
considered an idiom, let alone a "common idiom".
I certainly never saw it in any C code nor have seen it mentioned
as idiomatic code [to prevent compiler warning messages]. - This is
IMO just sick; in all respects. Compilers not warning about it (you
may have just missed to complete the RHS expression), programmers
working around a compiler deficiency by code that just rises more
questions (than solving any issue).
>> So it makes perfect sense for the compiler not to warn about it!
(Obviously mileages on that vary.)
>
> Wouldn't it just be easier and clearer to write: int a = 0;
> and be done with it?
Indeed! - More generally, there's a [general, non-language specific]
coding _idiom_ to ("always", sort of) initialize your variables, and
this is certainly part of many coding guidelines and recommendations
I've seen.
>
>> "int a = a + 1;", on the other hand, clearly attempts to read the value
>> of "a" before it is initialised, and a warning is issued if
>> "-Wuninitialized" is enabled. This warning is part of "-Wall".
>
> How is: int a = a + 1;
> conceptually different from: int a = a;
>
> Both are expressions involving 'a'.
> Isn't 'a' being used un-initialised in both cases?
>
> (You have to know the value of 'a' in order to evaluate the expression: a)
Yes. (Unless it's really an "idiom"; then we can justify every idea
we like by that classification.)
Janis
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <643-408-1753@kylheku.com> |
|---|---|
| Date | 2025-03-18 19:11 +0000 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <20250318120705.662@kylheku.com> |
| In reply to | #391312 |
On 2025-03-18, Janis Papanagnou <janis_papanagnou+ng@hotmail.com> wrote: > On 18.03.2025 19:04, Kenny McCormack wrote: >> In article <vrc75b$2r4lt$1@dont-email.me>, >> David Brown <david.brown@hesbynett.no> wrote: >> ... >>>> gcc won't warn until you say '-Wextra', and then only for: >>>> >>>> int a = a + 1; >>> >>> People would not normally write "int a = a;". It is used as a common >>> idiom meaning "I know it is not clear to the compiler that the variable >>> is always initialised before use, but /I/ know it is - so disable the >>> use-without-initialisation warnings for this variable". > > Wow! - It would never have occurred to me that "int a = a;" being > considered an idiom, let alone a "common idiom". Suppose the program is well-defined with "int a;"; just the compiler is not smart enough to analyze it, and so it warns about a potential use of an uninitialized variable. When you add this "idiom", you may be introducing undefined behavior into the declaration. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-03-19 15:56 +0100 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrelvn$12ddq$1@dont-email.me> |
| In reply to | #391312 |
On 18/03/2025 19:36, Janis Papanagnou wrote: > On 18.03.2025 19:04, Kenny McCormack wrote: >> In article <vrc75b$2r4lt$1@dont-email.me>, >> David Brown <david.brown@hesbynett.no> wrote: >> ... >>>> gcc won't warn until you say '-Wextra', and then only for: >>>> >>>> int a = a + 1; >>> >>> People would not normally write "int a = a;". It is used as a common >>> idiom meaning "I know it is not clear to the compiler that the variable >>> is always initialised before use, but /I/ know it is - so disable the >>> use-without-initialisation warnings for this variable". > > Wow! - It would never have occurred to me that "int a = a;" being > considered an idiom, let alone a "common idiom". > It is certainly an idiom, and certainly viewed by gcc as a way to avoid an "uninitialized" warning (unless "-Winit-self" is also enabled), and it is an idiom I have seen documented in at least one other compiler (though I can't remember which - I've read many compiler manuals over the decades). But judging from the posts here, it may not be a "common" idiom. (And I am not suggesting it is a /good/ idiom. It's not one I use myself, and I have "-Winit-self" in my list of standard warning flags because it is conceivable that I write "int a = a;" in error. But there are lots of idioms and common practices in C that I don't like personally.) As far as I understand it (and I hope to be corrected if I am wrong), "int a = a;" is not undefined behaviour as long as the implementation does not have trap values for "int". It simply leaves "a" as an unspecified value - just like "int a;" does. Thus it is not in any way "worse" than "int a;" as far as C semantics are concerned. Any difference is a matter of implementation - and the usual implementation effect is to disable "not initialised" warnings. It is in much the same category as "(void) x;", which is an idiom for skipping an "unused variable" or "unused parameter" warning.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2025-03-19 16:38 +0000 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <aqCCP.590465$SZca.348513@fx13.iad> |
| In reply to | #391353 |
David Brown <david.brown@hesbynett.no> writes: >On 18/03/2025 19:36, Janis Papanagnou wrote: >> On 18.03.2025 19:04, Kenny McCormack wrote: >>> In article <vrc75b$2r4lt$1@dont-email.me>, >>> David Brown <david.brown@hesbynett.no> wrote: >>> ... >>>>> gcc won't warn until you say '-Wextra', and then only for: >>>>> >>>>> int a = a + 1; >>>> >>>> People would not normally write "int a = a;". It is used as a common >>>> idiom meaning "I know it is not clear to the compiler that the variable >>>> is always initialised before use, but /I/ know it is - so disable the >>>> use-without-initialisation warnings for this variable". >> >> Wow! - It would never have occurred to me that "int a = a;" being >> considered an idiom, let alone a "common idiom". >> > >It is certainly an idiom, and certainly viewed by gcc as a way to avoid >an "uninitialized" warning (unless "-Winit-self" is also enabled), and >it is an idiom I have seen documented in at least one other compiler >(though I can't remember which - I've read many compiler manuals over >the decades). > >But judging from the posts here, it may not be a "common" idiom. > >(And I am not suggesting it is a /good/ idiom. It's not one I use >myself, and I have "-Winit-self" in my list of standard warning flags >because it is conceivable that I write "int a = a;" in error. But there >are lots of idioms and common practices in C that I don't like personally.) > > >As far as I understand it (and I hope to be corrected if I am wrong), >"int a = a;" is not undefined behaviour as long as the implementation >does not have trap values for "int". It simply leaves "a" as an >unspecified value - just like "int a;" does. Thus it is not in any way >"worse" than "int a;" as far as C semantics are concerned. Any >difference is a matter of implementation - and the usual implementation >effect is to disable "not initialised" warnings. > >It is in much the same category as "(void) x;", which is an idiom for >skipping an "unused variable" or "unused parameter" warning. > I would disagree with this last statement. (void)x is genuinely useful and has no ill side effects. 'int a = a;' is exactly the opposite - not useful and has potenial bad side effects. I've used the (void) construct when inline functions are defined in a header file, but not used by a source file that includes the header. (void) function will quiet the unused function warnings from the compiler without having to add #if to the header.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2025-03-19 14:29 -0700 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrfd0i$1n2ke$1@dont-email.me> |
| In reply to | #391359 |
On 3/19/2025 9:38 AM, Scott Lurndal wrote:
> David Brown <david.brown@hesbynett.no> writes:
>> On 18/03/2025 19:36, Janis Papanagnou wrote:
>>> On 18.03.2025 19:04, Kenny McCormack wrote:
>>>> In article <vrc75b$2r4lt$1@dont-email.me>,
>>>> David Brown <david.brown@hesbynett.no> wrote:
>>>> ...
>>>>>> gcc won't warn until you say '-Wextra', and then only for:
>>>>>>
>>>>>> int a = a + 1;
>>>>>
>>>>> People would not normally write "int a = a;". It is used as a common
>>>>> idiom meaning "I know it is not clear to the compiler that the variable
>>>>> is always initialised before use, but /I/ know it is - so disable the
>>>>> use-without-initialisation warnings for this variable".
>>>
>>> Wow! - It would never have occurred to me that "int a = a;" being
>>> considered an idiom, let alone a "common idiom".
>>>
>>
>> It is certainly an idiom, and certainly viewed by gcc as a way to avoid
>> an "uninitialized" warning (unless "-Winit-self" is also enabled), and
>> it is an idiom I have seen documented in at least one other compiler
>> (though I can't remember which - I've read many compiler manuals over
>> the decades).
>>
>> But judging from the posts here, it may not be a "common" idiom.
>>
>> (And I am not suggesting it is a /good/ idiom. It's not one I use
>> myself, and I have "-Winit-self" in my list of standard warning flags
>> because it is conceivable that I write "int a = a;" in error. But there
>> are lots of idioms and common practices in C that I don't like personally.)
>>
>>
>> As far as I understand it (and I hope to be corrected if I am wrong),
>> "int a = a;" is not undefined behaviour as long as the implementation
>> does not have trap values for "int". It simply leaves "a" as an
>> unspecified value - just like "int a;" does. Thus it is not in any way
>> "worse" than "int a;" as far as C semantics are concerned. Any
>> difference is a matter of implementation - and the usual implementation
>> effect is to disable "not initialised" warnings.
>>
>> It is in much the same category as "(void) x;", which is an idiom for
>> skipping an "unused variable" or "unused parameter" warning.
>>
>
> I would disagree with this last statement. (void)x is genuinely
> useful and has no ill side effects. 'int a = a;' is exactly
> the opposite - not useful and has potenial bad side effects.
>
> I've used the (void) construct when inline functions are defined
> in a header file, but not used by a source file that includes the
> header. (void) function will quiet the unused function warnings
> from the compiler without having to add #if to the header.
The scares me a bit:
_____________________
#include <stdio.h>
int main() {
int a = 666;
{
// Humm... Odd to me...
int a = a;
printf("%d", a);
}
return 0;
}
_____________________
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-03-20 09:39 +0100 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrgk82$2qpu6$1@dont-email.me> |
| In reply to | #391377 |
On 19/03/2025 22:29, Chris M. Thomasson wrote:
>
> The scares me a bit:
> _____________________
> #include <stdio.h>
>
> int main() {
>
> int a = 666;
>
> {
> // Humm... Odd to me...
> int a = a;
>
> printf("%d", a);
> }
>
> return 0;
> }
Yes, that is an unfortunate consequence of the scoping in C - on the
line "int a = a;", the new "a" is initialised with its own unspecified
value, not with the value of the outer "a".
If the scope of the new variable did not start until after the
initialisation, then it would have allowed a number of possibilities
that would be a lot more useful than the "disable warnings about
uninitialised variables" effect or initialisers which refer to their own
address. For example :
int a = 123;
{
int a = a;
// local copy that does not affect the outer one
...
int a = 123;
{
long long int a = a;
// Local copy that with expanded size
...
for (int a = 0; a < 100; a++) {
const int a = a;
// "Lock" the loop index to catch errors
As it is, you need to do something like :
for (int a = 0; a < 100; a++) {
const int _a = a;
const int a = _a;
// "Lock" the loop index to catch errors
[toc] | [prev] | [next] | [standalone]
| From | bart <bc@freeuk.com> |
|---|---|
| Date | 2025-03-20 11:59 +0000 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrgvue$35029$1@dont-email.me> |
| In reply to | #391387 |
On 20/03/2025 08:39, David Brown wrote:
> On 19/03/2025 22:29, Chris M. Thomasson wrote:
>>
>> The scares me a bit:
>> _____________________
>> #include <stdio.h>
>>
>> int main() {
>>
>> int a = 666;
>>
>> {
>> // Humm... Odd to me...
>> int a = a;
>>
>> printf("%d", a);
>> }
>>
>> return 0;
>> }
>
> Yes, that is an unfortunate consequence of the scoping in C - on the
> line "int a = a;", the new "a" is initialised with its own unspecified
> value, not with the value of the outer "a".
So the inner 'a' wasn't supposed to mysteriously inherit the outer a's
value? (Perhaps due to sharing the same location.) Since the compilers I
tried just showed zero not 666.
(Since this thread's subject was an alternative language, in that one it
can be done like this, but with the first 'a' outside the function since
there are no block scopes; the module is called 'test':
int a = 666
proc main =
int a := test.a
println a, test.a
The outer 'a' needs that qualifier to access it, in scopes where it
would be shadowed. Alternatively an alias can be created then that used
instead:
int a = 666
int b @ a
I don't know if any of these zero-run-time overhead methods are possible
in C. Possibly a union, but that's only if you can define 'a' yourself,
and is not an import for example. But then you have to permanently use
the union 'qualifier'.)
> If the scope of the new variable did not start until after the
> initialisation, then it would have allowed a number of possibilities
> that would be a lot more useful than the "disable warnings about
> uninitialised variables" effect or initialisers which refer to their own
> address. For example :
>
> int a = 123;
> {
> int a = a;
> // local copy that does not affect the outer one
> ...
>
>
> int a = 123;
> {
> long long int a = a;
> // Local copy that with expanded size
> ...
>
> for (int a = 0; a < 100; a++) {
> const int a = a;
> // "Lock" the loop index to catch errors
>
> As it is, you need to do something like :
>
> for (int a = 0; a < 100; a++) {
> const int _a = a;
> const int a = _a;
> // "Lock" the loop index to catch errors
You mean locking the loop index so it can't be modified? On the same
subject, that other language works like this:
for a in 0..99 do
a := 777 # not allowed
Loop variables, if not already defined as variables, are automatically
as read-only variables.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-03-20 15:46 +0100 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrh9o9$3e7sn$2@dont-email.me> |
| In reply to | #391392 |
On 20/03/2025 12:59, bart wrote:
> On 20/03/2025 08:39, David Brown wrote:
>> On 19/03/2025 22:29, Chris M. Thomasson wrote:
>>>
>>> The scares me a bit:
>>> _____________________
>>> #include <stdio.h>
>>>
>>> int main() {
>>>
>>> int a = 666;
>>>
>>> {
>>> // Humm... Odd to me...
>>> int a = a;
>>>
>>> printf("%d", a);
>>> }
>>>
>>> return 0;
>>> }
>>
>> Yes, that is an unfortunate consequence of the scoping in C - on the
>> line "int a = a;", the new "a" is initialised with its own unspecified
>> value, not with the value of the outer "a".
>
> So the inner 'a' wasn't supposed to mysteriously inherit the outer a's
> value? (Perhaps due to sharing the same location.) Since the compilers I
> tried just showed zero not 666.
No, the inner "a" is completely new and is initialised with itself. As
Keith has pointed out, this is UB - but of course compilers can choose
how to implement the code in question. gcc seems to pick "initialise to
0" as a default when you write "int a;" and then read "a", and does the
same for "int a = a;". Other compilers could choose to do something
different, such as pick a register for "a" and leave the value in the
register unchanged - in which case it might, by luck, pick up the value
of the outer "a".
>
>> If the scope of the new variable did not start until after the
>> initialisation, then it would have allowed a number of possibilities
>> that would be a lot more useful than the "disable warnings about
>> uninitialised variables" effect or initialisers which refer to their
>> own address. For example :
>>
>> int a = 123;
>> {
>> int a = a;
>> // local copy that does not affect the outer one
>> ...
>>
>>
>> int a = 123;
>> {
>> long long int a = a;
>> // Local copy that with expanded size
>> ...
>>
>> for (int a = 0; a < 100; a++) {
>> const int a = a;
>> // "Lock" the loop index to catch errors
>>
>> As it is, you need to do something like :
>>
>> for (int a = 0; a < 100; a++) {
>> const int _a = a;
>> const int a = _a;
>> // "Lock" the loop index to catch errors
>
> You mean locking the loop index so it can't be modified?
Yes.
[toc] | [prev] | [next] | [standalone]
| From | wij <wyniijj5@gmail.com> |
|---|---|
| Date | 2025-03-20 23:13 +0800 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <9b5f3e86dd67128bb6612523ae17a7368b97284a.camel@gmail.com> |
| In reply to | #391406 |
On Thu, 2025-03-20 at 15:46 +0100, David Brown wrote:
> On 20/03/2025 12:59, bart wrote:
> > On 20/03/2025 08:39, David Brown wrote:
> > > On 19/03/2025 22:29, Chris M. Thomasson wrote:
> > > >
> > > > The scares me a bit:
> > > > _____________________
> > > > #include <stdio.h>
> > > >
> > > > int main() {
> > > >
> > > > int a = 666;
> > > >
> > > > {
> > > > // Humm... Odd to me...
> > > > int a = a;
> > > >
> > > > printf("%d", a);
> > > > }
> > > >
> > > > return 0;
> > > > }
> > >
> > > Yes, that is an unfortunate consequence of the scoping in C - on the
> > > line "int a = a;", the new "a" is initialised with its own unspecified
> > > value, not with the value of the outer "a".
> >
> > So the inner 'a' wasn't supposed to mysteriously inherit the outer a's
> > value? (Perhaps due to sharing the same location.) Since the compilers I
> > tried just showed zero not 666.
>
> No, the inner "a" is completely new and is initialised with itself. As
> Keith has pointed out, this is UB - but of course compilers can choose
> how to implement the code in question. gcc seems to pick "initialise to
> 0" as a default when you write "int a;" and then read "a", and does the
> same for "int a = a;". Other compilers could choose to do something
> different, such as pick a register for "a" and leave the value in the
> register unchanged - in which case it might, by luck, pick up the value
> of the outer "a".
Yes, it (self-reference) should an UB like divide by zero error.
https://sourceforge.net/projects/cscall/files/MisFiles/ClassGuidelines.txt/download
.....[cut]
This guideline has no strong opinion on how this self-ops should be handled,
yet (it is like divided by zero error). Implement may check the self-ops (not
generally doable) and return ELOOP. Working around might be needed since the
intent mostly assumes the argument is passed by value, nonetheless a
theoretical bug might be thus hidden.
IMO, if the compiler sees it, it should issue at least a warning.
> >
> > > If the scope of the new variable did not start until after the
> > > initialisation, then it would have allowed a number of possibilities
> > > that would be a lot more useful than the "disable warnings about
> > > uninitialised variables" effect or initialisers which refer to their
> > > own address. For example :
> > >
> > > int a = 123;
> > > {
> > > int a = a;
> > > // local copy that does not affect the outer one
> > > ...
> > >
> > >
> > > int a = 123;
> > > {
> > > long long int a = a;
> > > // Local copy that with expanded size
> > > ...
> > >
> > > for (int a = 0; a < 100; a++) {
> > > const int a = a;
> > > // "Lock" the loop index to catch errors
> > >
> > > As it is, you need to do something like :
> > >
> > > for (int a = 0; a < 100; a++) {
> > > const int _a = a;
> > > const int a = _a;
> > > // "Lock" the loop index to catch errors
> >
> > You mean locking the loop index so it can't be modified?
>
> Yes.
>
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2025-03-20 02:02 -0700 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <864izooz0w.fsf@linuxsc.com> |
| In reply to | #391359 |
scott@slp53.sl.home (Scott Lurndal) writes: > David Brown <david.brown@hesbynett.no> writes: > >> On 18/03/2025 19:36, Janis Papanagnou wrote: >> >>> On 18.03.2025 19:04, Kenny McCormack wrote: >>> >>>> In article <vrc75b$2r4lt$1@dont-email.me>, >>>> David Brown <david.brown@hesbynett.no> wrote: >>>> ... >>>> >>>>>> gcc won't warn until you say '-Wextra', and then only for: >>>>>> >>>>>> int a = a + 1; >>>>> >>>>> People would not normally write "int a = a;". It is used as a >>>>> common idiom meaning "I know it is not clear to the compiler >>>>> that the variable is always initialised before use, but /I/ know >>>>> it is - so disable the use-without-initialisation warnings for >>>>> this variable". >>> >>> Wow! - It would never have occurred to me that "int a = a;" being >>> considered an idiom, let alone a "common idiom". >> >> It is certainly an idiom, and certainly viewed by gcc as a way to >> avoid an "uninitialized" warning (unless "-Winit-self" is also >> enabled), and it is an idiom I have seen documented in at least one >> other compiler (though I can't remember which - I've read many >> compiler manuals over the decades). >> >> But judging from the posts here, it may not be a "common" idiom. >> >> (And I am not suggesting it is a /good/ idiom. It's not one I use >> myself, and I have "-Winit-self" in my list of standard warning >> flags because it is conceivable that I write "int a = a;" in error. >> But there are lots of idioms and common practices in C that I don't >> like personally.) >> >> >> As far as I understand it (and I hope to be corrected if I am >> wrong), "int a = a;" is not undefined behaviour as long as the >> implementation does not have trap values for "int". It simply >> leaves "a" as an unspecified value - just like "int a;" does. Thus >> it is not in any way "worse" than "int a;" as far as C semantics >> are concerned. Any difference is a matter of implementation - and >> the usual implementation effect is to disable "not initialised" >> warnings. >> >> It is in much the same category as "(void) x;", which is an idiom >> for skipping an "unused variable" or "unused parameter" warning. > > I would disagree with this last statement. (void)x is genuinely > useful and has no ill side effects. 'int a = a;' is exactly > the opposite - not useful and has potenial bad side effects. I concur except that I recommend using (void)&x rather than (void)x, because (void)&x is safer. If x is volatile qualified, for example, the expression (void)x actually does something, and must not be compiled away, whereas (void)&x does not have these properties.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2025-03-20 15:57 +0100 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <vrhadc$3e7sn$3@dont-email.me> |
| In reply to | #391388 |
On 20/03/2025 10:02, Tim Rentsch wrote: > scott@slp53.sl.home (Scott Lurndal) writes: >> I would disagree with this last statement. (void)x is genuinely >> useful and has no ill side effects. 'int a = a;' is exactly >> the opposite - not useful and has potenial bad side effects. > > I concur except that I recommend using (void)&x rather than (void)x, > because (void)&x is safer. If x is volatile qualified, for example, > the expression (void)x actually does something, and must not be > compiled away, whereas (void)&x does not have these properties. I would recommend knowing which variables are volatile and which are not, so that the issue does not arise. Casting a volatile variable to void does "something", but what that "something" is is implementation-defined and can vary between compilers. Doing things to volatiles other than clear, simple reads or writes is a risk - the semantics are not fully defined in the C standards, implementations vary, and it is not at all uncommon for implementations to be inconsistent or buggy in that area. This is why C++ has deprecated many uses of volatile objects. So if you actually want to read a volatile variable but ignore the results (as you might well want to do for hardware device registers), it's best to do : auto dummy = volatile_var; (void) dummy; rather than (void) volatile_var;
[toc] | [prev] | [next] | [standalone]
| From | Kaz Kylheku <643-408-1753@kylheku.com> |
|---|---|
| Date | 2025-03-19 17:07 +0000 |
| Subject | Re: int a = a (Was: Bart's Language) |
| Message-ID | <20250319095922.207@kylheku.com> |
| In reply to | #391353 |
On 2025-03-19, David Brown <david.brown@hesbynett.no> wrote: > On 18/03/2025 19:36, Janis Papanagnou wrote: >> On 18.03.2025 19:04, Kenny McCormack wrote: >>> In article <vrc75b$2r4lt$1@dont-email.me>, >>> David Brown <david.brown@hesbynett.no> wrote: >>> ... >>>>> gcc won't warn until you say '-Wextra', and then only for: >>>>> >>>>> int a = a + 1; >>>> >>>> People would not normally write "int a = a;". It is used as a common >>>> idiom meaning "I know it is not clear to the compiler that the variable >>>> is always initialised before use, but /I/ know it is - so disable the >>>> use-without-initialisation warnings for this variable". >> >> Wow! - It would never have occurred to me that "int a = a;" being >> considered an idiom, let alone a "common idiom". >> > > It is certainly an idiom, and certainly viewed by gcc as a way to avoid > an "uninitialized" warning (unless "-Winit-self" is also enabled), and > it is an idiom I have seen documented in at least one other compiler > (though I can't remember which - I've read many compiler manuals over > the decades). I think that this "idiom" is a complete fluke, except in that compiler where it was documented. It's easy to see how it can arise "naturally" in a compiler which has warnings about both uses of uninitialized variables, and about variables being left uninitialized. In the "int a = a;" declaration, the initializing expression "a" is in the scope of a. Suppose the compiler, when processing the declaration, begins by extending the compile-time scope object with the name "a", and seeing that an initializer is present in the syntax, it flags "a" as being initialized. That suppresses any diagnostics about a not being initialized. Then it subsequently processes the initializing expression "a". At that point "a" is flagged initialized, and so no diagnostic occurs for the use of uninitialized "a". That's a bug in the compiler, not an idiom. "a" is positively *not* initialized until the initializing expression is evaluated. The compiler must *not* set this "initialized" flag in the scope information until it has compiled the initializing expression and moved on to the next declarator, declaration or statement. That way when it is code-walking the initializing expression, it will encounter "a" and correctly report that it's being accessed without having been initialized. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal Mastodon: @Kazinator@mstdn.ca
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2025-03-19 13:34 -0700 |
| Subject | Re: int a = a |
| Message-ID | <87sen8u5d5.fsf@nosuchdomain.example.com> |
| In reply to | #391353 |
David Brown <david.brown@hesbynett.no> writes:
[...]
> As far as I understand it (and I hope to be corrected if I am wrong),
Your hope is about to be fulfilled.
> "int a = a;" is not undefined behaviour as long as the implementation
> does not have trap values for "int". It simply leaves "a" as an
> unspecified value - just like "int a;" does. Thus it is not in any
> way "worse" than "int a;" as far as C semantics are concerned. Any
> difference is a matter of implementation - and the usual
> implementation effect is to disable "not initialised" warnings.
The behavior is undefined. In C11 and later (N1570 6.3.2.1p2):
Except when [...] an lvalue that does not have array type is
converted to the value stored in the designated object (and is no
longer an lvalue); this is called lvalue conversion.
[...]
If the lvalue designates an object of automatic storage duration that
could have been declared with the register storage class (never had
its address taken), and that object is uninitialized (not declared
with an initializer and no assignment to it has been performed prior
to use), the behavior is undefined.
> It is in much the same category as "(void) x;", which is an idiom for
> skipping an "unused variable" or "unused parameter" warning.
Unless I'm missing something, `(void)x` also has undefined beahvior
if x is uninitialized, though it's very likely to do nothing in
practice.
Long digression follows.
The "could have been declared with the register storage class" seems
quite odd. And in fact it is quite odd.
It's tempting to assume that `int n = n;` did not have undefined
behavior prior to C11, or that accessing an automatic object whose
address has not been taken does not have undefined behavior even
in C11 or later, but it's not that simple.
In C90, the non-normative Annex G (renamed to Annex J in later
editions) says:
The behavior in the following circumstances is undefined:
[...]
- The value of an uninitialized object that has automatic storage
duration is used before a value is assigned (6.5.7).
6.5.7 discusses initialization, and says that "If an object that
has automatic storage duration is not initialized explicitly, its
value is indeterminate", and C90's definition of "undefined behavior"
explicitly refers to use of indeterminately valued objects, though
it's not 100% clear that using an indeterminate value *always*
has undefined behavior.
So in C90, `int n = n;` explicitly had undefined behavior, even if
all possible bit representations for an object of type int correspond
to valid values (C90 didn't mention "trap representations").
C99 added a definition for "indeterminate value": "either an
unspecified value or a trap representation", and drops the mention
of indeterminate values in the definition of "undefined behavior".
It dropped the reference to uninitialized objects in Annex G/J.
I believe that in C99, `int n = n;` is well defined *if* int
has no trap representations, or if the representation stored in
the memory occupied by n happens not to be a trap representation.
If int has trap representations, and that memory happens to contain
such a representation, the behavior is undefined.
I found a discussion in comp.std.c from 2023, subject "Does reading
an uninitialized object have undefined behavior?".
The discontinued IA-64/Itanium processor had something called
"NaT", "Not a Thing". NaT representations exist only in CPU
registers, not in memory. (Imagine an extra bit for each register
indicating whether the register contains a "thing".) A NaT allows
for representations that act like C trap representations (called
non-value representations in C23) even for types with no trap
representations (for example where all 2**N possible representations
correspond to valid values) -- but again, only in CPU registers.
https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_338.htm
So the "could have been declared with the register storage class"
wording was added in C11 specifically to cater to the IA64. This
change would have been superfluous in C90, where the behavior was
undefined anyway, but is a semantically significant change between
C99 and C11. (If some future CPU has something like NaT that can
be stored in memory, the wording might need to be updated yet again.)
My takeaway is that if it requires this much research to determine
whether accessing the value of an uninitialized object has undefined
behavior (in which circumstances and which edition of the standard),
I'll just avoid doing so altogether. I'll initialize objects
when they're defined whenever practical. If it's not practical
for some reason, I won't initialize it with some dummy value; I'll
leave it uninitialized so the compiler has a chance to warn me if
I accidentally use it before assigning a value to it.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web