Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #112054 > unrolled thread
| Started by | Steve Keller <keller@no.invalid> |
|---|---|
| First post | 2017-06-12 18:34 +0200 |
| Last post | 2017-06-13 12:13 -0400 |
| Articles | 20 on this page of 42 — 13 participants |
Back to article view | Back to comp.lang.c
Hexadecimal float constants Steve Keller <keller@no.invalid> - 2017-06-12 18:34 +0200
Re: Hexadecimal float constants "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-12 12:44 -0400
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-12 10:54 -0700
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-12 11:26 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-12 19:38 +0100
Re: Hexadecimal float constants scott@slp53.sl.home (Scott Lurndal) - 2017-06-12 18:45 +0000
Re: Hexadecimal float constants Robert Wessel <robertwessel2@yahoo.com> - 2017-06-12 13:54 -0500
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-12 20:40 +0100
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-12 13:06 -0700
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-12 13:37 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-12 22:22 +0100
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-12 16:01 -0700
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-12 16:36 -0700
Re: Hexadecimal float constants jameskuyper@verizon.net - 2017-06-12 12:39 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-12 18:42 +0100
Re: Hexadecimal float constants Thomas David Rivers <rivers@dignus.com> - 2017-06-12 17:27 -0400
Re: Hexadecimal float constants "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-12 18:03 -0400
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-12 23:31 +0100
Re: Hexadecimal float constants Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-13 00:10 +0100
Re: Hexadecimal float constants jacobnavia <jacob@jacob.remcomp.fr> - 2017-06-13 01:33 +0200
Re: Hexadecimal float constants Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-13 01:10 +0100
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-12 16:01 -0700
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-12 17:00 -0700
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-13 07:51 -0700
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 09:17 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-13 17:45 +0100
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 11:58 -0700
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-13 12:57 -0700
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 13:01 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-13 22:11 +0100
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 14:22 -0700
Re: Hexadecimal float constants "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-13 17:43 -0400
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 14:48 -0700
Re: Hexadecimal float constants bartc <bc@freeuk.com> - 2017-06-13 23:03 +0100
Re: Hexadecimal float constants GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-06-14 01:30 +0200
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-13 12:24 -0700
Re: Hexadecimal float constants jacobnavia <jacob@jacob.remcomp.fr> - 2017-06-13 21:52 +0200
Re: Hexadecimal float constants Keith Thompson <kst-u@mib.org> - 2017-06-13 13:12 -0700
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-13 16:18 -0700
Re: Hexadecimal float constants Ike Naar <ike@iceland.freeshell.org> - 2017-06-14 21:28 +0000
Re: Hexadecimal float constants supercat@casperkitty.com - 2017-06-12 15:21 -0700
Re: Hexadecimal float constants Thomas David Rivers <rivers@dignus.com> - 2017-06-13 12:13 -0400
Page 1 of 3 [1] 2 3 Next page →
| From | Steve Keller <keller@no.invalid> |
|---|---|
| Date | 2017-06-12 18:34 +0200 |
| Subject | Hexadecimal float constants |
| Message-ID | <ohmfqn$q4l$1@gioia.aioe.org> |
Hm, until a few days ago, I thought I know the C standard quite well.
Now, there are a number of surprises, like the exact meaning of
tentative definitions, scope of variables, and now hexadecimal float
constants.
I read in the thread "High quality resources for learning modern C?"
that 0x1234e-1 is an illegal preprocessing token, and in fact, gcc and
clang refuse it:
xf.c:3:9: error: invalid suffix "-1" on integer constant
int x = 0x1234e-1;
Searching the standard, I found the reason for this surprising
behavior. The preprocessor doesn't scan for the C constants, which
consist of integer-constant, floating-constant, enumeration-constant,
and character-constant, but instead it scans for pp-number, which
allows "0x1234e-1" as a preprossing token, which then becomes a token
that is not a legal C token.
But what is the reason for this definition? Why does the preprocessor
not simply look for the C tokens (plus header-names for #include),
which would produce the (expected) token sequence "0x1234e", "-" , "1"?
Steve
[toc] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-12 12:44 -0400 |
| Message-ID | <3ebbcdb0-2c89-8e08-43a3-c54fe22fe426@verizon.net> |
| In reply to | #112054 |
On 06/12/2017 12:34 PM, Steve Keller wrote: > Hm, until a few days ago, I thought I know the C standard quite well. > Now, there are a number of surprises, like the exact meaning of > tentative definitions, scope of variables, and now hexadecimal float > constants. > > I read in the thread "High quality resources for learning modern C?" > that 0x1234e-1 is an illegal preprocessing token, and in fact, gcc and > clang refuse it: > > xf.c:3:9: error: invalid suffix "-1" on integer constant > int x = 0x1234e-1; > > Searching the standard, I found the reason for this surprising > behavior. The preprocessor doesn't scan for the C constants, which > consist of integer-constant, floating-constant, enumeration-constant, > and character-constant, but instead it scans for pp-number, which > allows "0x1234e-1" as a preprossing token, which then becomes a token > that is not a legal C token. > > But what is the reason for this definition? Why does the preprocessor > not simply look for the C tokens (plus header-names for #include), > which would produce the (expected) token sequence "0x1234e", "-" , "1"? That's addressed in the Rationale: "The notion of preprocessing numbers was introduced to simplify the description of preprocessing. It provides a means of talking about the tokenization of strings that look like numbers, or initial substrings of numbers, prior to their semantic interpretation. In the interests of keeping the description simple, occasional spurious forms are scanned as preprocessing numbers. For example, 0x123E+1 is a single token under the rules. The C89 Committee felt that it was better to tolerate such anomalies than burden the preprocessor with a more exact, and exacting, lexical specification. It felt that this anomaly was no worse than the principle under which the characters a+++++b are tokenized as a ++ ++ + b (an invalid expression), even though the tokenization a ++ + ++ b would yield a syntactically correct expression. In both cases, exercise of reasonable precaution in coding style avoids surprises."
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-06-12 10:54 -0700 |
| Message-ID | <b71d7769-536a-487d-a141-b7b1214362df@googlegroups.com> |
| In reply to | #112057 |
On Monday, June 12, 2017 at 11:44:08 AM UTC-5, James R. Kuyper wrote: > The C89 Committee felt that it was better to tolerate such > anomalies than burden the preprocessor with a more exact, and exacting, > lexical specification. It felt that this anomaly was no worse than the > principle under which the characters a+++++b are tokenized as a ++ ++ + > b (an invalid expression), even though the tokenization a ++ + ++ b > would yield a syntactically correct expression. In both cases, exercise > of reasonable precaution in coding style avoids surprises." Inserting token boundaries in a sequence of plus signs so as to handle a+++++b with the greediest clustering of plus signs that will parse would require that the tokenizer know whether "a" is an array or a number, which would not be possible if processing stages are handled sequentially. By contrast, it is unlikely that any non-contrived strictly conforming programs would rely upon compilers' inability to recognize a token boundary between a hex constant ending in "E" and a trailing plus sign, or--for that matter--upon a compiler's regarding 1.23E+5 as three tokens, the first of which is "1.23E" and must be followed by a plus sign and an integer literal, and allowing the use of ## to join such a "number needing exponent" token to a + sign. Fun puzzle: produce a strictly-conforming program which would return 1 on an implementation that conforms to the standard, and 0 on an implementation that would regard a + or - sign that follows any hex constant as a token boundary, even if the last digit of the constant happens to be "e" or "E". It is possible, but I would think it unlikely that any such programs have ever been written except for compiler testing or other contrived purposes.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-12 11:26 -0700 |
| Message-ID | <lna85dgj0b.fsf@kst-u.example.com> |
| In reply to | #112065 |
supercat@casperkitty.com writes:
> On Monday, June 12, 2017 at 11:44:08 AM UTC-5, James R. Kuyper wrote:
>> The C89 Committee felt that it was better to tolerate such
>> anomalies than burden the preprocessor with a more exact, and exacting,
>> lexical specification. It felt that this anomaly was no worse than the
>> principle under which the characters a+++++b are tokenized as a ++ ++ +
>> b (an invalid expression), even though the tokenization a ++ + ++ b
>> would yield a syntactically correct expression. In both cases, exercise
>> of reasonable precaution in coding style avoids surprises."
>
> Inserting token boundaries in a sequence of plus signs so as to handle
> a+++++b with the greediest clustering of plus signs that will parse would
> require that the tokenizer know whether "a" is an array or a number, which
> would not be possible if processing stages are handled sequentially.
How so? I can't think of any other tokenization than a ++ + ++ b that
would yield a syntactically valid expression, regardless of how `a` is
declared/defined. (Of course the standard requires it to be tokenized
as a ++ ++ + b, which is a syntax error, again regardless of how `a` and
`b` are delcared/defined.)
> By contrast, it is unlikely that any non-contrived strictly conforming
> programs would rely upon compilers' inability to recognize a token
> boundary between a hex constant ending in "E" and a trailing plus sign,
> or--for that matter--upon a compiler's regarding 1.23E+5 as three tokens,
> the first of which is "1.23E" and must be followed by a plus sign and an
> integer literal, and allowing the use of ## to join such a "number needing
> exponent" token to a + sign.
1.23E+5 is a perfectly valid floating constant. The example we were
discussing was 0x1234e-1 .
> Fun puzzle: produce a strictly-conforming program which would return 1 on
> an implementation that conforms to the standard, and 0 on an implementation
> that would regard a + or - sign that follows any hex constant as a token
> boundary, even if the last digit of the constant happens to be "e" or "E".
> It is possible, but I would think it unlikely that any such programs have
> ever been written except for compiler testing or other contrived purposes.
I don't know whether there is such a program -- but so what?
Processing strictly conforming programs is not the only requirement
the standard places on an implementation. Implementations are also
required to diagnose violations of syntax rules and constraints,
and 1.23E+5 is a constraint violation (6.4p2).
(Incidentally, a strictly conforming program cannot return 1, only 0,
EXIT_SUCCESS, or EXIT_FAILURE.)
--
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 | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-12 19:38 +0100 |
| Message-ID | <XcB%A.22191$l11.17681@fx01.am4> |
| In reply to | #112069 |
On 12/06/2017 19:26, Keith Thompson wrote: > (Incidentally, a strictly conforming program cannot return 1, only 0, > EXIT_SUCCESS, or EXIT_FAILURE.) > My gcc defines EXIT_FAILURE as 1. Is it non-conforming then? Actually, all my compilers do. They must ALL be non-conforming! Or do they know something you don't? -- bartc
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2017-06-12 18:45 +0000 |
| Message-ID | <zjB%A.63568$aW5.57253@fx21.iad> |
| In reply to | #112070 |
bartc <bc@freeuk.com> writes: >On 12/06/2017 19:26, Keith Thompson wrote: > >> (Incidentally, a strictly conforming program cannot return 1, only 0, >> EXIT_SUCCESS, or EXIT_FAILURE.) >> > >My gcc defines EXIT_FAILURE as 1. > >Is it non-conforming then? Do you really not understand? gcc is not a strictly conforming program. The programs compiled with gcc may or may not be, and aren't if they use 'exit(1)' instead of 'exit(EXIT_FAILURE)'.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2017-06-12 13:54 -0500 |
| Message-ID | <lcotjcpk0u9hf7p9gpu9i4iiesjbsr676d@4ax.com> |
| In reply to | #112070 |
On Mon, 12 Jun 2017 19:38:49 +0100, bartc <bc@freeuk.com> wrote: >On 12/06/2017 19:26, Keith Thompson wrote: > >> (Incidentally, a strictly conforming program cannot return 1, only 0, >> EXIT_SUCCESS, or EXIT_FAILURE.) >> > >My gcc defines EXIT_FAILURE as 1. > >Is it non-conforming then? > >Actually, all my compilers do. They must ALL be non-conforming! Or do >they know something you don't? No, it's just that EXIT_FAILURE *may* be something other than 1, so returning an explicit 1, instead of EXIT_FAILURE, may not have the desired effect on some implementations.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-12 20:40 +0100 |
| Message-ID | <h6C%A.181270$6r7.142834@fx34.am4> |
| In reply to | #112073 |
On 12/06/2017 19:54, Robert Wessel wrote: > On Mon, 12 Jun 2017 19:38:49 +0100, bartc <bc@freeuk.com> wrote: > >> On 12/06/2017 19:26, Keith Thompson wrote: >> >>> (Incidentally, a strictly conforming program cannot return 1, only 0, >>> EXIT_SUCCESS, or EXIT_FAILURE.) >>> >> >> My gcc defines EXIT_FAILURE as 1. >> >> Is it non-conforming then? >> >> Actually, all my compilers do. They must ALL be non-conforming! Or do >> they know something you don't? > > > No, it's just that EXIT_FAILURE *may* be something other than 1, so > returning an explicit 1, instead of EXIT_FAILURE, may not have the > desired effect on some implementations. Well, EXIT_FAILURE defined as 1 seems to be fine on Windows. And it seems to be fine on Linux. I don't have any other OSes to hand check what they use. But even with those two, someone who's going spend a decade or more programming only for those OSes shouldn't be unduly worried about hard-coding a 1. Since 0 means success, you would expect anything else, including 1, to indicate failure.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-12 13:06 -0700 |
| Message-ID | <ln1sqpgeci.fsf@kst-u.example.com> |
| In reply to | #112077 |
bartc <bc@freeuk.com> writes:
> On 12/06/2017 19:54, Robert Wessel wrote:
>> On Mon, 12 Jun 2017 19:38:49 +0100, bartc <bc@freeuk.com> wrote:
>>> On 12/06/2017 19:26, Keith Thompson wrote:
>>>> (Incidentally, a strictly conforming program cannot return 1, only 0,
>>>> EXIT_SUCCESS, or EXIT_FAILURE.)
>>>
>>> My gcc defines EXIT_FAILURE as 1.
>>>
>>> Is it non-conforming then?
>>>
>>> Actually, all my compilers do. They must ALL be non-conforming! Or do
>>> they know something you don't?
>>
>> No, it's just that EXIT_FAILURE *may* be something other than 1, so
>> returning an explicit 1, instead of EXIT_FAILURE, may not have the
>> desired effect on some implementations.
>
> Well, EXIT_FAILURE defined as 1 seems to be fine on Windows. And it
> seems to be fine on Linux.
>
> I don't have any other OSes to hand check what they use.
>
> But even with those two, someone who's going spend a decade or more
> programming only for those OSes shouldn't be unduly worried about
> hard-coding a 1. Since 0 means success, you would expect anything else,
> including 1, to indicate failure.
That wasn't the point. The point was about *strictly conforming
programs*.
(Now that I think about it, it's not clear that `return 1;` violates
strict conformance, since the definition of that term refers to a
program's *output*, not to the status it returns to the environment.)
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2017-06-12 13:37 -0700 |
| Message-ID | <ff149710-bb43-445e-a2f1-cc0974921344@googlegroups.com> |
| In reply to | #112069 |
On Monday, June 12, 2017 at 1:26:19 PM UTC-5, Keith Thompson wrote: > How so? I can't think of any other tokenization than a ++ + ++ b that > would yield a syntactically valid expression, regardless of how `a` is > declared/defined. (Of course the standard requires it to be tokenized > as a ++ ++ + b, which is a syntax error, again regardless of how `a` and > `b` are delcared/defined.) If a is an array and b is an int, the expression would be valid if tokenized as either "a + + + ++ b" or "a + + + + + b". If a is an int and b is an array, it would be valid if tokenized as "a ++ + + + b" or "a + + + + + b". In neither case would "a++ + ++b" be a valid parse. > > By contrast, it is unlikely that any non-contrived strictly conforming > > programs would rely upon compilers' inability to recognize a token > > boundary between a hex constant ending in "E" and a trailing plus sign, > > or--for that matter--upon a compiler's regarding 1.23E+5 as three tokens, > > the first of which is "1.23E" and must be followed by a plus sign and an > > integer literal, and allowing the use of ## to join such a "number needing > > exponent" token to a + sign. > > 1.23E+5 is a perfectly valid floating constant. The example we were > discussing was 0x1234e-1 . The simplest way to make floating-point numbers like 1.23E+5 "work" would be to treat such values as a sequence of tokens and then have the parser assemble them. An implementation that processed things that way would need to adjust the behavior of ## to allow for e.g. 1.23E##+5, but that would not be difficult. Other than the ability to use ## to assemble values, is any other purpose served by treating 1.23E+5 as one token rather than as either three tokens "1.23E + 5", or five tokens "1 . 23E + 5"? The scanner for the latter would seem much simpler than one which has to regard a + or - as part of a token when preceded by an "e" or "E" but not when preceded by other characters. > > Fun puzzle: produce a strictly-conforming program which would return 1 on > > an implementation that conforms to the standard, and 0 on an implementation > > that would regard a + or - sign that follows any hex constant as a token > > boundary, even if the last digit of the constant happens to be "e" or "E". > > It is possible, but I would think it unlikely that any such programs have > > ever been written except for compiler testing or other contrived purposes. > > I don't know whether there is such a program -- but so what? > Processing strictly conforming programs is not the only requirement > the standard places on an implementation. Implementations are also > required to diagnose violations of syntax rules and constraints, > and 1.23E+5 is a constraint violation (6.4p2). Implementations are free to add extensions provided that they document them, and provided that they don't interfere with the behavior of any strictly- conforming program. Since the documentation requirement would be meaningless in cases where use of an extension would trigger a diagnostic, the only way in which the permission to include extensions would be meaningful would be if documented extensions are exempt from the diagnostic requirement. One could argue that implementations wanting to document as an extension their acceptance of 0x1e+x as equivalent to "0x1e + x" would be required to ensure that sequence of characters behaves as a single token in cases where a strictly-conforming program defines x as a macro and that sequence of characters is stringized after macro substitution, but I see no useful purpose to be served by requiring such behavior.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-12 22:22 +0100 |
| Message-ID | <9CD%A.25370$7A4.1849@fx19.am4> |
| In reply to | #112083 |
On 12/06/2017 21:37, supercat@casperkitty.com wrote: > On Monday, June 12, 2017 at 1:26:19 PM UTC-5, Keith Thompson wrote: > The simplest way to make floating-point numbers like 1.23E+5 "work" would > be to treat such values as a sequence of tokens and then have the parser > assemble them. An implementation that processed things that way would need > to adjust the behavior of ## to allow for e.g. 1.23E##+5, but that would > not be difficult. Other than the ability to use ## to assemble values, is > any other purpose served by treating 1.23E+5 as one token rather than as > either three tokens "1.23E + 5", or five tokens "1 . 23E + 5"? The scanner > for the latter would seem much simpler It would be too simple. Not much more advanced than the character sequence it starts with. There are also lots of ways to specify floats: (1 e 5), (1 . e 5), (. 4e -5), (0 . f) etc. The parser just wants to see a token that says 'this is a floating point constant with value X', and has the given type (float, double, long double which may be specified with a suffix). It shouldn't be doing the tokeniser's job. But the requirement for C's preprocessing makes everything unnecessarily more complicated. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-12 16:01 -0700 |
| Message-ID | <lnshj4g69r.fsf@kst-u.example.com> |
| In reply to | #112083 |
supercat@casperkitty.com writes:
> On Monday, June 12, 2017 at 1:26:19 PM UTC-5, Keith Thompson wrote:
>> How so? I can't think of any other tokenization than a ++ + ++ b that
>> would yield a syntactically valid expression, regardless of how `a` is
>> declared/defined. (Of course the standard requires it to be tokenized
>> as a ++ ++ + b, which is a syntax error, again regardless of how `a` and
>> `b` are delcared/defined.)
>
> If a is an array and b is an int, the expression would be valid if
> tokenized as either "a + + + ++ b" or "a + + + + + b". If a is an int
> and b is an array, it would be valid if tokenized as "a ++ + + + b" or
> "a + + + + + b". In neither case would "a++ + ++b" be a valid parse.
I hadn't thought about the unary "+" operator, but you've snipped
relevant context. You were talking about *parsing*, not about whether
the expression might be invalid for other reasons.
Yes, `a + + + + + b` can be valid if a and b are of numeric type.
[...]
>> 1.23E+5 is a perfectly valid floating constant. The example we were
>> discussing was 0x1234e-1 .
>
> The simplest way to make floating-point numbers like 1.23E+5 "work" would
> be to treat such values as a sequence of tokens and then have the parser
> assemble them.
The language already defines how 1.23E+5 works. We recently spent a
great deal of time discussing the minor glitch involving preprocessing
numbers like `0x1234e-1`. It is, in my opinion, not a problem worth
solving.
[...]
> Implementations are free to add extensions provided that they document them,
> and provided that they don't interfere with the behavior of any strictly-
> conforming program. Since the documentation requirement would be
> meaningless in cases where use of an extension would trigger a diagnostic,
> the only way in which the permission to include extensions would be
> meaningful would be if documented extensions are exempt from the diagnostic
> requirement.
>
> One could argue that implementations wanting to document as an extension
> their acceptance of 0x1e+x as equivalent to "0x1e + x" would be required
> to ensure that sequence of characters behaves as a single token in cases
> where a strictly-conforming program defines x as a macro and that sequence
> of characters is stringized after macro substitution, but I see no useful
> purpose to be served by requiring such behavior.
Wait, now you're talking about "0x1e+x"? Where did that final "x" come
from?
An implementation could have an extension whereby it treats `0x1e+x` as
equivalent to `0x1e + x`. Having and documenting such an extension does
not relieve it of the requirement to diagnose `0x1e+x` as a constraint
violation. It can issue a non-fatal warning and then proceed to treat
it as `0x1e+x`, and/or it can do so without a warning in some
non-conforming mode.
--
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 | supercat@casperkitty.com |
|---|---|
| Date | 2017-06-12 16:36 -0700 |
| Message-ID | <5a041473-e77f-4548-8e82-6da24e9420a8@googlegroups.com> |
| In reply to | #112096 |
On Monday, June 12, 2017 at 6:01:28 PM UTC-5, Keith Thompson wrote: > The language already defines how 1.23E+5 works. We recently spent a > great deal of time discussing the minor glitch involving preprocessing > numbers like `0x1234e-1`. It is, in my opinion, not a problem worth > solving. > Wait, now you're talking about "0x1e+x"? Where did that final "x" come > from? Maybe I misread the pp-number grammar, in which case there might not be any cases where a strictly-conforming program could get parsed differently based upon whether it regards "e+" specially within a number even when that number starts with "0x". > An implementation could have an extension whereby it treats `0x1e+x` as > equivalent to `0x1e + x`. Having and documenting such an extension does > not relieve it of the requirement to diagnose `0x1e+x` as a constraint > violation. It can issue a non-fatal warning and then proceed to treat > it as `0x1e+x`, and/or it can do so without a warning in some > non-conforming mode. In what case would the requirement to document extensions impose any burden on any implementations, if it did not relieve implementations of the requirement of diagnosing code which uses such extension? Is there any reason an implementation could not satisfy the requirement by simply adding a "-fsilly-diagnostic" switch which, when applied, would output "Warning: Silly diagnostic requested" and specifying that compliance may require use of that switch?
[toc] | [prev] | [next] | [standalone]
| From | jameskuyper@verizon.net |
|---|---|
| Date | 2017-06-12 12:39 -0700 |
| Message-ID | <e7e9378a-107d-4ea5-82d2-e2ff69f1969e@googlegroups.com> |
| In reply to | #112065 |
On Monday, June 12, 2017 at 1:54:39 PM UTC-4, supe...@casperkitty.com wrote: > On Monday, June 12, 2017 at 11:44:08 AM UTC-5, James R. Kuyper wrote: > > The C89 Committee felt that it was better to tolerate such > > anomalies than burden the preprocessor with a more exact, and exacting, > > lexical specification. It felt that this anomaly was no worse than the > > principle under which the characters a+++++b are tokenized as a ++ ++ + > > b (an invalid expression), even though the tokenization a ++ + ++ b > > would yield a syntactically correct expression. In both cases, exercise > > of reasonable precaution in coding style avoids surprises." You snipped out every indication I made in my message that I was quoting text written by someone else (except for the final '"' character). Please don't do that. It gives the impression that I'm claiming to be the author of those words, which I most certainly didn't. I just cut and pasted them from the Rationale. ... > By contrast, it is unlikely that any non-contrived strictly conforming > programs would rely upon compilers' inability to recognize a token > boundary between a hex constant ending in "E" and a trailing plus sign, That's true: such code is a constraint violation, and therefore cannot occur in strictly conforming code. ... > Fun puzzle: produce a strictly-conforming program which would return 1 on > an implementation that conforms to the standard, and 0 on an implementation > that would regard a + or - sign that follows any hex constant as a token > boundary, even if the last digit of the constant happens to be "e" or "E". > It is possible, but I would think it unlikely that any such programs have > ever been written except for compiler testing or other contrived purposes. "Each preprocessing token that is converted to a token shall have the lexical form of a keyword, an identifier, a constant, a string literal, or a punctuator." 6.4p2. A hexadecimal constant immediately followed by a + or - would be parsed as a pp-number (6.4.8), possibly including some following characters, when preprocessing tokens are identified. It would therefore be parsed as a single preprocessing token. When the attempt is made to convert it to an ordinary token, it can never qualify as any of tho things listed in 6.4p2. Hexadecimal constants necessarily start with 0x (6.4.4.1p1). No identifier, character constant, string literal, or punctuator can start with a 0x (6.4.1, 6.4.2, 6.4.4.4p1), 6.4.6p1. The only types of numeric constants that can start with 0x and also contain a '+' or a '-' are floating point constants, but in that case, the '+' or '-' must be immediately preceded by 'p' or 'P' (6.4.4.2p1). Neither of those characters is allowed in a hexadecimal constant. (6.4.4.1p1). Therefore, any "+ or - sign that follows any hex constant" without any white space to separate them is a constraint violation, and therefore cannot appear in strictly conforming code.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-12 18:42 +0100 |
| Message-ID | <%nA%A.71499$kd6.66068@fx33.am4> |
| In reply to | #112054 |
On 12/06/2017 17:34, Steve Keller wrote:
> Hm, until a few days ago, I thought I know the C standard quite well.
> Now, there are a number of surprises, like the exact meaning of
> tentative definitions, scope of variables, and now hexadecimal float
> constants.
>
> I read in the thread "High quality resources for learning modern C?"
> that 0x1234e-1 is an illegal preprocessing token, and in fact, gcc and
> clang refuse it:
>
> xf.c:3:9: error: invalid suffix "-1" on integer constant
> int x = 0x1234e-1;
>
> Searching the standard, I found the reason for this surprising
> behavior. The preprocessor doesn't scan for the C constants, which
> consist of integer-constant, floating-constant, enumeration-constant,
> and character-constant, but instead it scans for pp-number, which
> allows "0x1234e-1" as a preprossing token, which then becomes a token
> that is not a legal C token.
>
> But what is the reason for this definition? Why does the preprocessor
> not simply look for the C tokens (plus header-names for #include),
> which would produce the (expected) token sequence "0x1234e", "-" , "1"?
Because preprocessing tokens are different. Sometimes they would be
illegal numeric values, such as:
089 // illegal octal constant
0FFF // illegal hex constant
because they might be stringified, or have other tokens prepended, to
end up with something that is a legal identifier or constant.
So the the 089 might become 1089 with the "1" prepended. 0FFF might
become 0x10FFF with "0x1" prepended, or the identifier "K0FFF"
There is little use for a 0x1234E-1 token however. (If you've read that
thread then probably you will know I don't care much for the preprocessor.)
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Thomas David Rivers <rivers@dignus.com> |
|---|---|
| Date | 2017-06-12 17:27 -0400 |
| Message-ID | <593F0753.9040003@dignus.com> |
| In reply to | #112054 |
Steve Keller wrote: >Hm, until a few days ago, I thought I know the C standard quite well. >Now, there are a number of surprises, like the exact meaning of >tentative definitions, scope of variables, and now hexadecimal float >constants. > >I read in the thread "High quality resources for learning modern C?" >that 0x1234e-1 is an illegal preprocessing token, and in fact, gcc and >clang refuse it: > > xf.c:3:9: error: invalid suffix "-1" on integer constant > int x = 0x1234e-1; > > > Are we sure those compilers are correct? Why isn't this the same as this declaration: int x = 0x1234e - 1 ; (with extra spaces to denote the C constants/expression I see there.) In looking at the standard - I don't see the error the compilers are reporting. That looks like a bug in the compilers? - Dave Rivers - -- rivers@dignus.com Work: (919) 676-0847 Get your mainframe programming tools at http://www.dignus.com
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-06-12 18:03 -0400 |
| Message-ID | <b401da97-da04-bf4d-0db1-1a62098725e8@verizon.net> |
| In reply to | #112089 |
On 06/12/2017 05:27 PM, Thomas David Rivers wrote:
> Steve Keller wrote:
>
>> Hm, until a few days ago, I thought I know the C standard quite well.
>> Now, there are a number of surprises, like the exact meaning of
>> tentative definitions, scope of variables, and now hexadecimal float
>> constants.
>>
>> I read in the thread "High quality resources for learning modern C?"
>> that 0x1234e-1 is an illegal preprocessing token, and in fact, gcc and
>> clang refuse it:
>>
>> xf.c:3:9: error: invalid suffix "-1" on integer constant
>> int x = 0x1234e-1;
>>
>>
>>
>
> Are we sure those compilers are correct?
Yes, they are, at least in this regard.
> Why isn't this the same as this declaration:
>
> int x = 0x1234e - 1 ;
Because the spaces force "0x1234e - 1" to be parsed as three separate
tokens. "0x1234e-1" has an 'e' between a pp-number and a sign character,
with no spaces separating them - that makes it parse as a pp-number.
> (with extra spaces to denote the C constants/expression I see there.)
>
> In looking at the standard - I don't see the error the compilers are
> reporting.
Let's follow the grammar rules given in 6.4.8p1:
"0": digit => pp-number
"0x": pp-number non-digit => pp-number
"0x1": pp-number digit => pp-number
"0x12": pp-number digit => pp-number
"0x123": pp-number digit => pp-number
"0x1234": pp-number digit => pp-number
"0x1234e-": pp-number e sign => pp-number
"0x1234e-1": pp-number digit => pp-number
Therefore, it gets parsed during translation phase 3 as a single
preprocessing token. During translation phase 7, each preprocessing
token is supposed to be converted to a single token; it's a constraint
violation if it can't be so parsed (6.4.2p4). It could be parsed as
three consecutive tokens {"0x1234e", "-", "1"}, but the constraint
requires that it be parsed as a single token.
The reason the Committee gave for using these rules to define a
pp-number is to keep the pre-processor simple - it's not until
translation phase 7 that the compiler has to do anything as complicated
as figuring out floating point constants. The current grammar has 9
rules for a pp-number, none of which has more than three elements.
Compare that with the number and complexity of the rules required to
define integer and floating point constants (6.4.4.1 and 6.4.4.2).
> That looks like a bug in the compilers?
It isn't.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-12 23:31 +0100 |
| Message-ID | <XCE%A.115227$MY.17784@fx14.am4> |
| In reply to | #112092 |
On 12/06/2017 23:03, James R. Kuyper wrote:
> On 06/12/2017 05:27 PM, Thomas David Rivers wrote:
>> Why isn't this the same as this declaration:
>>
>> int x = 0x1234e - 1 ;
> The reason the Committee gave for using these rules to define a
> pp-number is to keep the pre-processor simple
Which clearly hasn't worked.
- it's not until
> translation phase 7 that the compiler has to do anything as complicated
> as figuring out floating point constants.
Since it has to end up doing that anyway, there is no advantage.
And tokenising floating point is a hundred times simpler than the
macro-processing that needs to be done.
But rather than just do the tokenising of floating point and get it over
and done with, it's necessary to allow also these half-formed
Frankenstein versions of numbers that are neither integer, float, hex
nor octal, and keep hold of them for several more phases on the
off-chance that they might form part of another token that IS meaningful.
This is their idea of keeping things simple!
(Messing around building new tokens out of others would have been easier
with quoted tokens I think.
So longhex(7FFF, 000F) => 0x7FFF000F, would be invoked as
longhex('7FFF','000F'), with ## treating 'ABC' the same as ABC.
It means that tokenising of numeric constants could be completed
immediately, and tokens such as 7FFF are errors even in early phases.)
The current grammar has 9
> rules for a pp-number, none of which has more than three elements.
> Compare that with the number and complexity of the rules required to
> define integer and floating point constants (6.4.4.1 and 6.4.4.2).
>
>> That looks like a bug in the compilers?
>
> It isn't.
Half the compilers I tried do one thing with 0x1234E-1 (report as error)
and half do another (treat it as 0x1234E - 1). So there is no consensus.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-13 00:10 +0100 |
| Message-ID | <871sqoby56.fsf@bsb.me.uk> |
| In reply to | #112094 |
bartc <bc@freeuk.com> writes: <snip> > Half the compilers I tried do one thing with 0x1234E-1 (report as > error) and half do another (treat it as 0x1234E - 1). I thought that those compilers you cited before all used the same pre-processor code? If so, counting compilers is a little... odd. > So there is no consensus. There is consensus about what a standard conforming C compiler should do. Do any of the compilers that are derived from Hanson and Fraser's cpp code claim to be standard C compilers? If so, they simply have a bug. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | jacobnavia <jacob@jacob.remcomp.fr> |
|---|---|
| Date | 2017-06-13 01:33 +0200 |
| Message-ID | <ohn85u$ikh$1@dont-email.me> |
| In reply to | #112098 |
Le 13/06/2017 à 01:10, Ben Bacarisse a écrit : > bartc <bc@freeuk.com> writes: > <snip> >> Half the compilers I tried do one thing with 0x1234E-1 (report as >> error) and half do another (treat it as 0x1234E - 1). > > I thought that those compilers you cited before all used the same > pre-processor code? If so, counting compilers is a little... odd. > >> So there is no consensus. > > There is consensus about what a standard conforming C compiler should > do. Do any of the compilers that are derived from Hanson and Fraser's > cpp code claim to be standard C compilers? If so, they simply have a > bug. > Is it? The preprocessor that lcc is using was adapted from a one written by Dennis Ritchie. Yes, it doesn't process this fringe example as specified by todays standards. By some people standards, this is a bug. I will leave it as is.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web