Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #105736 > unrolled thread
| Started by | BartC <bc@freeuk.com> |
|---|---|
| First post | 2017-03-10 19:13 +0000 |
| Last post | 2017-03-12 12:51 +0000 |
| Articles | 20 on this page of 35 — 14 participants |
Back to article view | Back to comp.lang.c
Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-10 19:13 +0000
Re: Return statement: anything goes? John Bode <jfbode1029@gmail.com> - 2017-03-10 11:59 -0800
Re: Return statement: anything goes? Keith Thompson <kst-u@mib.org> - 2017-03-10 12:34 -0800
Re: Return statement: anything goes? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-10 20:17 +0000
Re: Return statement: anything goes? bart4858@gmail.com - 2017-03-10 13:17 -0800
Re: Return statement: anything goes? Ian Collins <ian-news@hotmail.com> - 2017-03-11 10:30 +1300
Re: Return statement: anything goes? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-11 01:25 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 12:11 +0000
Re: Return statement: anything goes? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-11 14:57 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 16:31 +0000
Re: Return statement: anything goes? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-11 17:47 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 17:57 +0000
Re: Return statement: anything goes? jameskuyper@verizon.net - 2017-03-11 10:59 -0800
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 19:34 +0000
Re: Return statement: anything goes? jameskuyper@verizon.net - 2017-03-11 11:59 -0800
Re: Return statement: anything goes? supercat@casperkitty.com - 2017-03-11 12:26 -0800
Re: Return statement: anything goes? supercat@casperkitty.com - 2017-03-11 12:22 -0800
Re: Return statement: anything goes? jameskuyper@verizon.net - 2017-03-11 12:42 -0800
Re: Return statement: anything goes? supercat@casperkitty.com - 2017-03-11 13:01 -0800
Re: Return statement: anything goes? Gordon Burditt <gordon@hammy.burditt.org> - 2017-03-13 16:25 -0500
Re: Return statement: anything goes? Gareth Owen <gwowen@gmail.com> - 2017-03-11 16:43 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 18:13 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 18:27 +0000
Re: Return statement: anything goes? gordonb.rlpr3@burditt.org (Gordon Burditt) - 2017-03-13 16:18 -0500
Re: Return statement: anything goes? supercat@casperkitty.com - 2017-03-11 12:44 -0800
Re: Return statement: anything goes? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-03-11 07:43 -0800
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-11 18:34 +0000
Re: Return statement: anything goes? Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-03-11 10:43 -0800
Re: Return statement: anything goes? Keith Thompson <kst-u@mib.org> - 2017-03-10 12:27 -0800
Re: Return statement: anything goes? Noob <root@127.0.0.1> - 2017-03-10 22:06 +0100
Re: Return statement: anything goes? bart4858@gmail.com - 2017-03-10 13:26 -0800
Re: Return statement: anything goes? antispam@math.uni.wroc.pl - 2017-03-12 05:29 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-12 10:52 +0000
Re: Return statement: anything goes? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-03-12 12:19 +0000
Re: Return statement: anything goes? BartC <bc@freeuk.com> - 2017-03-12 12:51 +0000
Page 1 of 2 [1] 2 Next page →
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-10 19:13 +0000 |
| Subject | Return statement: anything goes? |
| Message-ID | <o9utno$5tn$1@dont-email.me> |
This is something that came up last week, and was another example of C
compilers all reacting differently to the same errors.
In this case, whether or not a return statement is present, and whether
it returns the correct type of expression:
int V;
void A1(int x) { }
void A2(int x) { return;}
void A3(int x) { return 123;}
int B1(int x) { }
int B2(int x) { return;}
int B3(int x) { return 123;}
int B4(int x) { return &V;}
int B5(int x) { if (1) return x;}
void* C1(int x) { }
void* C2(int x) { return;}
void* C3(int x) { return 123;}
void* C4(int x) { return &V;}
int main(void) { } // M1
int main(void) { return;} // M2
int main(void) { return 123;} // M3
int main(void) { return &V;} // M4
(The main() variations were tested one at a time.)
A selection of Windows C compilers gave these errors and warnings with
default options (E = error, W = warning, dash = no error):
A1 A2 A3 B1 B2 B3 B4 B5 C1 C2 C3 C4 M1 M2 M3 M4
Pelles C - - W W E - E - - E E - - E - E
lccwin - - W W W - E W W W E - - W - W
DMC - - - - E - E - - - E - - - - E
gcc/tdm - - W - W - W - - W W - - W - W
Tiny C - - - - - - W - - - W - - - - W
MSVC'08 - - W W W - W - W W W - - - - -
(bartc - - E E E - E E E E E - * E - E)
The last row shows what I consider to be errors, where I wouldn't be
happy with a wrong or missing return statement making it into code that
is to be executed.
It does rather seem that compiling C code is something of a lucky dip!
Surely source code is either correct or it isn't? Or is part of the
problem an attempt to keep compatibility with lax code and lax compilers
of the past?
Anyway it seems to be lccwin that agrees most closely with my view of
what is right or wrong.
[* I assume special rules apply to main(), in that a missing return
statement, or return expression, is quietly replaced by 'return 0']
--
bartc
[toc] | [next] | [standalone]
| From | John Bode <jfbode1029@gmail.com> |
|---|---|
| Date | 2017-03-10 11:59 -0800 |
| Message-ID | <0a96e294-bd5c-4a52-9519-9f4748750cf2@googlegroups.com> |
| In reply to | #105736 |
On Friday, March 10, 2017 at 1:13:46 PM UTC-6, Bart wrote:
> This is something that came up last week, and was another example of C
> compilers all reacting differently to the same errors.
>
> In this case, whether or not a return statement is present, and whether
> it returns the correct type of expression:
>
> int V;
>
> void A1(int x) { }
> void A2(int x) { return;}
> void A3(int x) { return 123;}
>
> int B1(int x) { }
> int B2(int x) { return;}
> int B3(int x) { return 123;}
> int B4(int x) { return &V;}
> int B5(int x) { if (1) return x;}
>
> void* C1(int x) { }
> void* C2(int x) { return;}
> void* C3(int x) { return 123;}
> void* C4(int x) { return &V;}
>
> int main(void) { } // M1
> int main(void) { return;} // M2
> int main(void) { return 123;} // M3
> int main(void) { return &V;} // M4
>
> (The main() variations were tested one at a time.)
>
> A selection of Windows C compilers gave these errors and warnings with
> default options (E = error, W = warning, dash = no error):
>
> A1 A2 A3 B1 B2 B3 B4 B5 C1 C2 C3 C4 M1 M2 M3 M4
>
> Pelles C - - W W E - E - - E E - - E - E
> lccwin - - W W W - E W W W E - - W - W
> DMC - - - - E - E - - - E - - - - E
> gcc/tdm - - W - W - W - - W W - - W - W
> Tiny C - - - - - - W - - - W - - - - W
> MSVC'08 - - W W W - W - W W W - - - - -
>
> (bartc - - E E E - E E E E E - * E - E)
>
> The last row shows what I consider to be errors, where I wouldn't be
> happy with a wrong or missing return statement making it into code that
> is to be executed.
>
> It does rather seem that compiling C code is something of a lucky dip!
> Surely source code is either correct or it isn't? Or is part of the
> problem an attempt to keep compatibility with lax code and lax compilers
> of the past?
>
> Anyway it seems to be lccwin that agrees most closely with my view of
> what is right or wrong.
>
> [* I assume special rules apply to main(), in that a missing return
> statement, or return expression, is quietly replaced by 'return 0']
>
> --
> bartc
A3, B2, C2, and M2 are all clearly constraint violations (6.8.6.4) and
require a diagnostic to be issued.
B1 and C1 are undefined if the caller attempts to use the return value
(6.9.1), and undefined behavior doesn't require a diagnostic.
B5 won't result in undefined behavior as written, since the execution
path will always go through the return. I'd want the compiler to warn
me that there is a potential path of execution that doesn't have a return
statement, even if static analysis shows that path to be unreachable,
but that's a QoI issue.
M1 is allowed as of C99 - a "return 0;" is implied. Prior to that, I think
it fall in the same bucket as B1 and C1.
B4, C3, and M4 - I'm not sure. 6.8.6.4 says that values of types different
from the return type are converted as if by assignment, so I'd expect
a diagnostic if the expression type and the return type aren't compatible.
Footnote 160 says that since the return statement is *not* an assignment,
the overlap restriction of 6.5.16.1 doesn't apply.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-03-10 12:34 -0800 |
| Message-ID | <lny3wcg9al.fsf@kst-u.example.com> |
| In reply to | #105745 |
John Bode <jfbode1029@gmail.com> writes:
[...]
> B4, C3, and M4 - I'm not sure. 6.8.6.4 says that values of types different
> from the return type are converted as if by assignment, so I'd expect
> a diagnostic if the expression type and the return type aren't compatible.
> Footnote 160 says that since the return statement is *not* an assignment,
> the overlap restriction of 6.5.16.1 doesn't apply.
Type *compatibility* is not the issue. The term is sometimes
incorrectly used to refer to types that can be implicitly converted to
each other, but that's not what it means. Basically, two types are
"compatible" only if they're the same type, or in a few other cases.
The types that can be implicitly converted to each other are described
in the standard under simple assignment. The same rules apply to
initialization, argument passing, and the return statement.
--
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 | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-03-10 20:17 +0000 |
| Message-ID | <87o9x8yjgp.fsf@bsb.me.uk> |
| In reply to | #105736 |
BartC <bc@freeuk.com> writes:
> This is something that came up last week, and was another example of C
> compilers all reacting differently to the same errors.
>
> In this case, whether or not a return statement is present, and
> whether it returns the correct type of expression:
>
> int V;
>
> void A1(int x) { }
> void A2(int x) { return;}
> void A3(int x) { return 123;}
>
> int B1(int x) { }
> int B2(int x) { return;}
> int B3(int x) { return 123;}
> int B4(int x) { return &V;}
> int B5(int x) { if (1) return x;}
>
> void* C1(int x) { }
> void* C2(int x) { return;}
> void* C3(int x) { return 123;}
> void* C4(int x) { return &V;}
>
> int main(void) { } // M1
> int main(void) { return;} // M2
> int main(void) { return 123;} // M3
> int main(void) { return &V;} // M4
>
> (The main() variations were tested one at a time.)
>
> A selection of Windows C compilers gave these errors and warnings with
> default options (E = error, W = warning, dash = no error):
What's the point of that? By default, almost all C compilers implement
a language that is not C. If you are aiming for compatibility with some
popular compiler, then that's one whose behaviour you should copy and
the other are a distraction.
But if you are not, why burden yourself with the history they they are
all struggling with? I think you should do what you consider to be,
technically, best.
> A1 A2 A3 B1 B2 B3 B4 B5 C1 C2 C3 C4 M1 M2 M3 M4
>
> Pelles C - - W W E - E - - E E - - E - E
> lccwin - - W W W - E W W W E - - W - W
> DMC - - - - E - E - - - E - - - - E
> gcc/tdm - - W - W - W - - W W - - W - W
> Tiny C - - - - - - W - - - W - - - - W
> MSVC'08 - - W W W - W - W W W - - - - -
>
> (bartc - - E E E - E E E E E - * E - E)
>
> The last row shows what I consider to be errors, where I wouldn't be
> happy with a wrong or missing return statement making it into code
> that is to be executed.
Your compiler can generate any diagnostics you like, but if you are
implying that you would not generate code for some of these, then you
are compiling yet another C dialect, just like all the other compilers
listed do (in default mode).
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | bart4858@gmail.com |
|---|---|
| Date | 2017-03-10 13:17 -0800 |
| Message-ID | <e06a31f8-6c98-4fe3-a87f-aaddbef8d138@googlegroups.com> |
| In reply to | #105747 |
On Friday, 10 March 2017 20:18:05 UTC, Ben Bacarisse wrote: > Your compiler can generate any diagnostics you like, but if you are > implying that you would not generate code for some of these, then you > are compiling yet another C dialect, just like all the other compilers > listed do (in default mode). Huh? Choosing to ignore or not take seriously what are obvious errors (see other replies) is compiling a dialect of the language? My problem (and this is one example) is that if I'm too strict, then I may not be able to compile existing code that might have passed the lower standards of other compilers. And it is still illuminating that the same issue with a program can be ignored, or considered a warning rather than an error, depending on implementation. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2017-03-11 10:30 +1300 |
| Message-ID | <eigk7vFf3nbU1@mid.individual.net> |
| In reply to | #105762 |
On 03/11/17 10:17 AM, bart4858@gmail.com wrote: > > My problem (and this is one example) is that if I'm too strict, then > I may not be able to compile existing code that might have passed the > lower standards of other compilers. It isn't lower standards, it's what the compiler defaults to. If the compiler can't be made to enforce strict compliance, that's a bug. By the way I often hit this problem compiling poor opensource code written with gcc when compiling with Sun's cc which has a much stricter default mode. > And it is still illuminating that the same issue with a program can > be ignored, or considered a warning rather than an error, depending > on implementation. Where the standard requires a diagnostic, a warning is a diagnostic. If you want an error, use whatever option the compiler has to turn warnings into errors. -- Ian
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-03-11 01:25 +0000 |
| Message-ID | <87inngy57x.fsf@bsb.me.uk> |
| In reply to | #105762 |
bart4858@gmail.com writes:
> On Friday, 10 March 2017 20:18:05 UTC, Ben Bacarisse wrote:
>
>> Your compiler can generate any diagnostics you like, but if you are
>> implying that you would not generate code for some of these, then you
>> are compiling yet another C dialect, just like all the other compilers
>> listed do (in default mode).
>
> Huh? Choosing to ignore or not take seriously what are obvious errors
> (see other replies) is compiling a dialect of the language?
>
> My problem (and this is one example) is that if I'm too strict, then I
> may not be able to compile existing code that might have passed the
> lower standards of other compilers.
It's more a matter of matched the language standard. That's why
rejecting correct programs like:
#include <stdio.h>
int f(void) { puts("OK"); }
int main(void) { f(); }
would create a new dialect. Some compilers on your list may not support
modern C (especially by default), so a void function might be impossible
to define making code like
f() { puts("OK"); }
very common.
> And it is still illuminating that the same issue with a program can be
> ignored, or considered a warning rather than an error, depending on
> implementation.
I suppose so, but I'm not sure it illuminates anything very interesting.
C is old and has more distinct implementations than almost any other
language. That they differ in what to warn about is not really news to
many people.
You table did not have enough detail to see in any compilers were
missing required diagnostics of where rejecting program that should be
accepted, but such things would only illuminate the fact the compilers
have bugs.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-11 12:11 +0000 |
| Message-ID | <oa0pct$9ll$1@dont-email.me> |
| In reply to | #105778 |
On 11/03/2017 01:25, Ben Bacarisse wrote:
> bart4858@gmail.com writes:
>> My problem (and this is one example) is that if I'm too strict, then I
>> may not be able to compile existing code that might have passed the
>> lower standards of other compilers.
>
> It's more a matter of matched the language standard. That's why
> rejecting correct programs like:
>
> #include <stdio.h>
> int f(void) { puts("OK"); }
> int main(void) { f(); }
>
> would create a new dialect.
It would be a better, safer dialect then.
Suppose f() was defined in one module, and called from another which
makes use of its return value. Then the value returned is undefined.
The handful of tests I've done show that f generally returns either 0,
or whatever the last contents of the main return register were.
When f() returns a float, then it might return 0.0, -Nan, -1#IND00, or
again, whatever the last calculation was.
That's not the sort of behaviour I want in my programs.
The problem is that someone may have forgotten to put in a return statement.
(BTW the chart in the OP shows DMC with an 'entry' E against B2; it
should have been B3. So both DMC and Tiny C ignore the missing return
above.)
Another issue is when f() has one return type in one module, but a
different one in another (or even a completely different set of parameters).
That doesn't seem to be picked up at the minute by any C compilers, even
when all modules are compiled at the same time (unless the latest gcc
has some new option for it).
(My compiler however could detect that with little trouble, when sources
are available (obviously it can't detect it inside an already compiled
library!). But that's because all sources must be submitted and there
will be a global, shared symbol table for all modules.)
> Some compilers on your list may not support
> modern C (especially by default), so a void function might be impossible
> to define making code like
>
> f() { puts("OK"); }
>
> very common.
I've decided not to support functions declared with with () parameters,
nor old-style parameter declarations, nor implicit int. At some point
it's necessary to draw the line.
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-03-11 14:57 +0000 |
| Message-ID | <87d1dnyi73.fsf@bsb.me.uk> |
| In reply to | #105787 |
BartC <bc@freeuk.com> writes:
> On 11/03/2017 01:25, Ben Bacarisse wrote:
>> bart4858@gmail.com writes:
>
>>> My problem (and this is one example) is that if I'm too strict, then I
>>> may not be able to compile existing code that might have passed the
>>> lower standards of other compilers.
>>
>> It's more a matter of matched the language standard. That's why
>> rejecting correct programs like:
>>
>> #include <stdio.h>
>> int f(void) { puts("OK"); }
>> int main(void) { f(); }
>>
>> would create a new dialect.
>
> It would be a better, safer dialect then.
It would be safer. Some people would argue that a compiler that rejects
some C programs is not "better", so that one would be endlessly
debatable.
But this raises the question of why you would implement C at all. C has
all sorts of things you hate, so if you are not going to implement
standard C, why not implement something entirely "better" (by your own
criteria of course)?
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-11 16:31 +0000 |
| Message-ID | <oa18ji$l75$1@dont-email.me> |
| In reply to | #105791 |
On 11/03/2017 14:57, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
>
>> On 11/03/2017 01:25, Ben Bacarisse wrote:
>>> bart4858@gmail.com writes:
>>
>>>> My problem (and this is one example) is that if I'm too strict, then I
>>>> may not be able to compile existing code that might have passed the
>>>> lower standards of other compilers.
>>>
>>> It's more a matter of matched the language standard. That's why
>>> rejecting correct programs like:
>>>
>>> #include <stdio.h>
>>> int f(void) { puts("OK"); }
>>> int main(void) { f(); }
>>>
>>> would create a new dialect.
>>
>> It would be a better, safer dialect then.
>
> It would be safer. Some people would argue that a compiler that rejects
> some C programs is not "better", so that one would be endlessly
> debatable.
>
> But this raises the question of why you would implement C at all.
Just for fun. Also to see whether I can do it, and meet certain criteria
doing so:
(Being able to present the complete thing as one source file [currently
15Kloc]; being able to compile it as easily as Hello World; being able
run it just as easily; including everything needed in one executable;
being able to directly run programs from source; and being extremely
fast. And, a bit trickier, to have generated code not be that terrible.)
> C has
> all sorts of things you hate, so if you are not going to implement
> standard C, why not implement something entirely "better" (by your own
> criteria of course)?
I've already done that (and I'm using it to implement this C project).
But that needed a better, faster compiler; that project became this one
(compiling an entire C project from multiple sources), and I will get
back to the original purpose later.
What's interesting about the C version, is that while some aspects of
the language slow it down (preprocessor, all the quirks, and repeated
headers), others make it faster to compile. It'll be interesting to see
how far I get.
That I don't like C so much is not so important; I don't have to use it!
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-03-11 17:47 +0000 |
| Message-ID | <877f3vyach.fsf@bsb.me.uk> |
| In reply to | #105796 |
BartC <bc@freeuk.com> writes:
> On 11/03/2017 14:57, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
>>
>>> On 11/03/2017 01:25, Ben Bacarisse wrote:
>>>> bart4858@gmail.com writes:
>>>
>>>>> My problem (and this is one example) is that if I'm too strict, then I
>>>>> may not be able to compile existing code that might have passed the
>>>>> lower standards of other compilers.
>>>>
>>>> It's more a matter of matched the language standard. That's why
>>>> rejecting correct programs like:
>>>>
>>>> #include <stdio.h>
>>>> int f(void) { puts("OK"); }
>>>> int main(void) { f(); }
>>>>
>>>> would create a new dialect.
>>>
>>> It would be a better, safer dialect then.
>>
>> It would be safer. Some people would argue that a compiler that rejects
>> some C programs is not "better", so that one would be endlessly
>> debatable.
>>
>> But this raises the question of why you would implement C at all.
>
> Just for fun.
Ah, I see. You can do pretty much what you like then. Making it
slightly different to standard C is fine by the criterion of doing it
for fun.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-11 17:57 +0000 |
| Message-ID | <oa1dle$6qa$1@dont-email.me> |
| In reply to | #105799 |
On 11/03/2017 17:47, Ben Bacarisse wrote: > BartC <bc@freeuk.com> writes: > >> On 11/03/2017 14:57, Ben Bacarisse wrote: >>> But this raises the question of why you would implement C at all. >> >> Just for fun. > > Ah, I see. You can do pretty much what you like then. Well, it also has to work. That means compiling and running other people's code /without changes/. At the minute, that is difficult enough to do even with existing compilers. (That is, taking something like an open source project, and making it compile, build and run with /any/ of the C compilers I have available. Or just /one/. If a program passes that test, then it means I have a chance of doing the same.) -- bartc
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-03-11 10:59 -0800 |
| Message-ID | <b592c7be-be2e-49ec-8a43-668d64dcd412@googlegroups.com> |
| In reply to | #105800 |
On Saturday, March 11, 2017 at 12:57:52 PM UTC-5, Bart wrote: > On 11/03/2017 17:47, Ben Bacarisse wrote: > > BartC <bc@freeuk.com> writes: > > > >> On 11/03/2017 14:57, Ben Bacarisse wrote: > > >>> But this raises the question of why you would implement C at all. > >> > >> Just for fun. > > > > Ah, I see. You can do pretty much what you like then. > > Well, it also has to work. That means compiling and running other > people's code /without changes/. So, what other code are you willing to require your compiler to accept without changes? You've got to limit it in some fashion. If you include all conforming programs to the list, you've created an impossible requirement. Code that is entirely correct, containing no syntax errors, constraint violations or undefined behavior may still contain code that behaves differently when compiled by different compilers, due to things that the C standard leaves unspecified. As far as the author of deliberately non-portable code is concerned, if it has different behavior when translated by some other implementations than it would have when translated by the target implementation, that different behavior is incorrect behavior. Therefore, the only way your compiler could produce the correct behavior is by knowing how the intended target implementation would handle such code - which is something your compiler could not figure out from the code itself. Do you want to restrict the code that your compiler is required to translate correctly to include all strictly conforming programs? If so, that comes close to requiring full conformance with the C standard. That would certainly be the case for the particular issues you raised in this thread. "strictly conforming code" is pretty restrictive - there's very few real-world programs that qualify. Do you want your compiler to correctly translate a wider variety of programs? If so, you need to decide how wide a variety you want it to handle.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-03-11 19:34 +0000 |
| Message-ID | <oa1jbf$uis$1@dont-email.me> |
| In reply to | #105810 |
On 11/03/2017 18:59, jameskuyper@verizon.net wrote: > On Saturday, March 11, 2017 at 12:57:52 PM UTC-5, Bart wrote: >> On 11/03/2017 17:47, Ben Bacarisse wrote: >>> BartC <bc@freeuk.com> writes: >>> >>>> On 11/03/2017 14:57, Ben Bacarisse wrote: >> >>>>> But this raises the question of why you would implement C at all. >>>> >>>> Just for fun. >>> >>> Ah, I see. You can do pretty much what you like then. >> >> Well, it also has to work. That means compiling and running other >> people's code /without changes/. > > So, what other code are you willing to require your compiler to accept without changes? You've got to limit it in some fashion. If you include all conforming programs to the list, you've created an impossible requirement. Code that is entirely correct, containing no syntax errors, constraint violations or undefined behavior may still contain code that behaves differently when compiled by different compilers, due to things that the C standard leaves unspecified. As far as the author of deliberately non-portable code is concerned, if it has different behavior when translated by some other implementations than it would have when translated by the target implementation, that different behavior is incorrect behavior. Therefore, the only way your compiler could produce the correct behavior is by knowing how the intended target implementation would handle such code - which is something your compiler could not figure out from the code itself. > > Do you want to restrict the code that your compiler is required to translate correctly to include all strictly conforming programs? If so, that comes close to requiring full conformance with the C standard. That would certainly be the case for the particular issues you raised in this thread. > > "strictly conforming code" is pretty restrictive - there's very few real-world programs that qualify. Do you want your compiler to correctly translate a wider variety of programs? If so, you need to decide how wide a variety you want it to handle. My aim would be to try compile anything that works with my range of Windows C compilers (Pelles C, lccwin, DMC, Tiny C, gcc and, possibly, MSVC, although that one is harder to invoke). Such a project will also have passed these obstacles: * A configuration step (that might depend on importing most of Linux) * Having build instructions hidden inside a makefile * Not being dependent on a specific set of compile options * Not requiring features, extensions or macro defines from a specific compiler * Not needing a library only available with a specific implementation. Compiling Linux projects would be more difficult. (As I would rely on Linux header files full of stuff I can't deal with. I can't compile gcc headers because they are full of gcc-specific features, and I can't easily prise Linux headers and gcc headers apart.) Apart from that, there will be practical problems (I won't have the range of headers that normally come with a compiler, such as windows.h; I would need to piggy-back onto an existing compiler's files; it gets messy.) Also I won't initially implement VLAs (although I'm not sure if MSVC has them either; my 2008 version doesn't seem to). Actually compiling user-code will be the least of the problems, and I am prepared to comment out checks to make the code pass. (Code that I write or generate myself, I don't anticipate problems with. I already write it to work on any compiler and on either Windows or Linux.) -- bartc
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-03-11 11:59 -0800 |
| Message-ID | <80a4f767-164d-4a3b-bed2-10df43056623@googlegroups.com> |
| In reply to | #105812 |
On Saturday, March 11, 2017 at 2:34:56 PM UTC-5, Bart wrote: > On 11/03/2017 18:59, jameskuyper@verizon.net wrote: > > On Saturday, March 11, 2017 at 12:57:52 PM UTC-5, Bart wrote: > >> On 11/03/2017 17:47, Ben Bacarisse wrote: > >>> BartC <bc@freeuk.com> writes: > >>> > >>>> On 11/03/2017 14:57, Ben Bacarisse wrote: > >> > >>>>> But this raises the question of why you would implement C at all. > >>>> > >>>> Just for fun. > >>> > >>> Ah, I see. You can do pretty much what you like then. > >> > >> Well, it also has to work. That means compiling and running other > >> people's code /without changes/. > > > > So, what other code are you willing to require your compiler to accept without changes? You've got to limit it in some fashion. If you include all conforming programs to the list, you've created an impossible requirement. Code that is entirely correct, containing no syntax errors, constraint violations or undefined behavior may still contain code that behaves differently when compiled by different compilers, due to things that the C standard leaves unspecified. As far as the author of deliberately non-portable code is concerned, if it has different behavior when translated by some other implementations than it would have when translated by the target implementation, that different behavior is incorrect behavior. Therefore, the only way your compiler could produce the correct behavior is by knowing how the intended target implementation would handle such code - which is something your compiler could not figure out from the code itself. > > > > Do you want to restrict the code that your compiler is required to translate correctly to include all strictly conforming programs? If so, that comes close to requiring full conformance with the C standard. That would certainly be the case for the particular issues you raised in this thread. > > > > "strictly conforming code" is pretty restrictive - there's very few real-world programs that qualify. Do you want your compiler to correctly translate a wider variety of programs? If so, you need to decide how wide a variety you want it to handle. > > My aim would be to try compile anything that works with my range of > Windows C compilers (Pelles C, lccwin, DMC, Tiny C, gcc and, possibly, > MSVC, although that one is harder to invoke). That phrase could be interpreted two ways: 1. Your compiler is only intended to compile correctly code that can also be compiled correctly by all of those other compilers. 2. You compiler is intended to compile correctly any code that can be compiled correctly by any of those compilers. Option 1 is feasible, because it makes a very weak guarantee. I suspect that option 2 is infeasible, because it makes a much stronger guarantee.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-11 12:26 -0800 |
| Message-ID | <53e208f8-4430-47c1-af16-0d8c253aadeb@googlegroups.com> |
| In reply to | #105814 |
On Saturday, March 11, 2017 at 1:59:51 PM UTC-6, james...@verizon.net wrote: > That phrase could be interpreted two ways: > 1. Your compiler is only intended to compile correctly code that can also be compiled correctly by all of those other compilers. > > 2. You compiler is intended to compile correctly any code that can be compiled correctly by any of those compilers. > > Option 1 is feasible, because it makes a very weak guarantee. I suspect that option 2 is infeasible, because it makes a much stronger guarantee. If "compile correctly" means "behave identically to", then unless Bart is using a very limited selection of compilers, option 2 would be impossible. If some but not all compilers have a 16-bit "int", for example, then the ones with 16-bit "int" would be required to evaluate -1 > 0x8000 as 1, and those with a larger "int" type would be required to evaluate it as yielding 0, so it would be possible to have a single language which could "correctly" compile that in the same way as all of his existing compilers.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-11 12:22 -0800 |
| Message-ID | <e9ede432-117b-414b-8d6b-bc0e2ceae236@googlegroups.com> |
| In reply to | #105810 |
On Saturday, March 11, 2017 at 12:59:26 PM UTC-6, james...@verizon.net wrote:
> So, what other code are you willing to require your compiler to accept without changes? You've got to limit it in some fashion.
Were I designing a language based on C, the primary objective would be that
existing C code which is accepted by my language would have the same meaning
as in any common C implementations where it would have a defined meaning. As
a secondary objective, existing C code which would be rejected by my language
should be easily adaptable so as to work equally well in my language as in C.
The ability to run a substantial corpus of C code without modification would
be extremely desirable, but secondary to the above objectives.
Note that a non-C language could implement the first objective much more
effectively than a conforming C compiler since the C Standard would require
that something like:
int subcomp16(uint16_t x, uint16_t y, uint16_t z)
{
return x-y > z;
}
have different incompatible meanings in different implementations, which
means that any language where it is acceptable would fail my first criterion;
I would require that the result of a operations on "ordinary" short unsigned
types be clipped to 16 bits implicitly or implicitly (I'd also have other
unsigned types, recommended for use in new code, whose behavior would be
independent of the size of "int".
Code using e.g. "wrap32_t" could be easily be made to work on compilers which
included "uint32_t" which could represent values that "int" could not and
refuse compilation on other compilers [which would be preferable to compiling
but yielding errant behavior]. A compiler for the new language could accept
"wrap32_t" even if "int" was larger than 64 bits, since it would not be bound
by the C Standard's requirement to promote all integer types smaller than
"int".
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-03-11 12:42 -0800 |
| Message-ID | <c3b22bb3-0fa4-4b20-bbde-6e3a5dd65d30@googlegroups.com> |
| In reply to | #105818 |
On Saturday, March 11, 2017 at 3:22:15 PM UTC-5, supe...@casperkitty.com wrote: > On Saturday, March 11, 2017 at 12:59:26 PM UTC-6, james...@verizon.net wrote: > > So, what other code are you willing to require your compiler to accept > > without changes? You've got to limit it in some fashion. > > Were I designing a language based on C, the primary objective would be that > existing C code which is accepted by my language would have the same meaning > as in any common C implementations where it would have a defined meaning. And if two different very common C implementations gave the same code different defined meanings, how would you choose? Making good coherent design choices is more important than matching the behavior of other existing compilers. To think otherwise involves worshipping at the altar of "existing practice" rather than thinking for oneself as a compiler designer. Which, depending upon how poor one's skills as a compiler designer are, might be a wise decision.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-03-11 13:01 -0800 |
| Message-ID | <f2a2beec-892b-43b1-a949-346e6c0f33a0@googlegroups.com> |
| In reply to | #105820 |
On Saturday, March 11, 2017 at 2:42:33 PM UTC-6, james...@verizon.net wrote: > > Were I designing a language based on C, the primary objective would be that > > existing C code which is accepted by my language would have the same meaning > > as in any common C implementations where it would have a defined meaning. > > And if two different very common C implementations gave the same code different defined meanings, how would you choose? I would require that the code be adjusted in such fashion as to force one meaning or the other. If x, y, and z are all type uint16_t, I would tend to regard the expression "x-y > z" as defective *regardless* of its intended meaning; if using standard integer types, it should be written as something like (uint16_t)(x-y) > z or (int32_t)x-y > z depending upon which meaning was intended. Alternatively, ambiguity could be avoided by using variables declared as wrap16_t, on the presumption that a header would only define it if it (wrap16_t)0 - (wrap16_t)1 would yield (wrap16_t)65535. > Making good coherent design choices is more important than matching the behavior of other existing compilers. To think otherwise involves worshipping at the altar of "existing practice" rather than thinking for oneself as a compiler designer. Which, depending upon how poor one's skills as a compiler designer are, might be a wise decision. I don't "worship" existing practice, but do recognize that if many compilers on a certain platform behave a certain way, and a lot of program exploit such behavior, that's a pretty good sign that the behavior is useful, and compilers that don't support it may not really be suitable for the purposes those programs are trying to serve.
[toc] | [prev] | [next] | [standalone]
| From | Gordon Burditt <gordon@hammy.burditt.org> |
|---|---|
| Date | 2017-03-13 16:25 -0500 |
| Message-ID | <ReednRbmY-HGk1rFnZ2dnUU7-WWdnZ2d@posted.internetamerica> |
| In reply to | #105800 |
> (That is, taking something like an open source project, and making it > compile, build and run with /any/ of the C compilers I have available. > Or just /one/. If a program passes that test, then it means I have a > chance of doing the same.) Here's a challenge: Compile GCC with GCC, (same version in both cases0 using -Werror -Wall and get an executable with no source code changes.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web