Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #112054 > unrolled thread

Hexadecimal float constants

Started bySteve Keller <keller@no.invalid>
First post2017-06-12 18:34 +0200
Last post2017-06-13 12:13 -0400
Articles 20 on this page of 42 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#112054 — Hexadecimal float constants

FromSteve Keller <keller@no.invalid>
Date2017-06-12 18:34 +0200
SubjectHexadecimal 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]


#112057

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#112065

Fromsupercat@casperkitty.com
Date2017-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]


#112069

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#112070

Frombartc <bc@freeuk.com>
Date2017-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]


#112072

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-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]


#112073

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-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]


#112077

Frombartc <bc@freeuk.com>
Date2017-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]


#112080

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#112083

Fromsupercat@casperkitty.com
Date2017-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]


#112088

Frombartc <bc@freeuk.com>
Date2017-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]


#112096

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#112100

Fromsupercat@casperkitty.com
Date2017-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]


#112076

Fromjameskuyper@verizon.net
Date2017-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]


#112063

Frombartc <bc@freeuk.com>
Date2017-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]


#112089

FromThomas David Rivers <rivers@dignus.com>
Date2017-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]


#112092

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-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]


#112094

Frombartc <bc@freeuk.com>
Date2017-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]


#112098

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#112099

Fromjacobnavia <jacob@jacob.remcomp.fr>
Date2017-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