Writing single bits to a file

C

Charlie Gordon

Keith Thompson said:
Charlie Gordon said:
Of course, I'm not proposing ** to be a token, but x * *y to be
reinterpreted as fexp(x, y) if y is a numeric type. This trick can be
played on the parse tree if you have one, at code generation time, or on
the
fly if you generate code directly. The programmer would be more inclined
to
write x ** y or x**y, but it is parsed as x * *y. This trick would be
more
difficult to play in an interpreter with dynamic typing, but still
possible,
by sticking the appropriate behaviour to fexp(x, y) for y pointer type.
[...]

My gut reaction to this idea is: Ick.

I was expecting this. It was my first reaction too.
If I were designing a new language with a "**" operator, I'd just make
"**" a token. If "*" is also a unary operator, then "x * *y" would
require a space. The kind of special-case treatment you suggest is,
in my opinion, just too convoluted.

It is required for the sake of compatibility with current semantics of
binary * and unary *.
I like the way tokenization and analysis are separated in C. It makes
the language easier to implement and, more importantly, easier to
describe. A more complicated definition might allow "x+++++y" to be
legal, but at the cost of creating odd corner cases that couldn't be
resolved without detailed analysis of the standard.

I like the way tokenization works too. But extending the grammar without
clashes with the current semantics sometimes requires "contorted" ways.
There already are uncanny side effects with the unary * operator: `` x/*p''
does not parse like ''x / *p'' ;-). Javascript extended its C-like syntax
roots to include support for regular expression literals: support for the
/regex/ syntax requires feedback from the grammar into the lexer, but the
programmers need not be aware of this.
And if you're adding extensions to the language, it's not unlikely
that you'd eventually want to add operator overloading. How do you
overload "**" if it' a composite of "*" and "*", and how do you
interpret "x**y" if either interpretation could be correct?

Operator overloading in C++ does not allow redefining operations on scalar
types. It would be acceptable to restrain ** to operate only on types for
which x * (*p) does not have a meaning already.

What would be more surprising and make this idea unworkable is the bizarre
precedence it gives the fake ** operator: ``a*b**c'' would parse and
evaluate as ``(a * b) * (*c)'' effectively making ** less binding than *
(counter-intuitive), but ``a**b*c'' would parse and evaluate as ``(a * (*b))
* c'' making ** more binding than * in this case.

A more consistent proposal is to allow creating new custom operators and
tokens, with specified precedence and associativity, but no built-in
support. This way you keep compatibility with existing code that does not
make use of these 'extended' operators, and give proper support for
extending the syntax and grammar in a consistent and intuitive way. You
need a specific syntax for defining the new operators, preferably at the
preprocessing level:

#operator ** binary left 2.5 /* new token **, binary operator, left
associative, binds more than * / % */

double operator ** (double x, double y) { return fexp(x, y); }
 
C

Charlie Gordon

cr88192 said:
Keith Thompson said:
cr88192 said:
news:[email protected]... [...]
.5==x^.5==y // x equals 0.5 or y equals 0.5 but not both.
.8<x&.9>x
1.1==x|.9==y
x/.1
y*.2
z-.2
...

I always put around binary operators but a lot of programmers don't.

odd, I always thought the preceeding decimal digits were required.
at least in my parser, the number will not be recognized as a number,
unless it starts with a decimal digit, say, '0'...

Take a look at the syntax for a floating-constant, C99 6.4.4.2.

Just as a matter of style, I never use a leading or trailing decimal
point (I at least prepend or append a 0), but it's permitted.

ok, I missed that, having assumed the leading digits were required.

I am not sure if in-practice things are done this way, or not.
2 options here:
disallow floating point numbers lacking a numeric prefix ('.5' being
technically invalid);
adding a 'disambiguation rule', such that whitespace is required following
the dot if following the dot could ambiguously be confused as a
fractional-number.

'2^.3' would thus be invalid (parsed as '2 ^ .3'), and would thus have to
be written:
'2^. 3'.

'^:', is also possible, but IMO uglier, and has potential implications
(the above operator style at least has precedent in a few certain specific
functional languages...).

'^,' is also possible, since these operators are not allowed standalone or
in suffix position.

(just here looking for a rule I can generalize to create a number of
auxilary operators is all).

.. as a prefix for operators seems to work for this purpose: as long as it is
not part of the previous token, it can serve as the leading part of a multi
character token. The following character cannot be a digit, letter,
underscore or another .

3 .+ 4 is unambiguous.

You define a bunch of new tokens this way:

..! .@ .% .^ .& .* .( .) .- .+ .= .| .{ .} .[ .] .: .< .> ./ .? .~

none of them are particularly appealing.
 
D

David Thompson

cr88192 wrote:
FROM void*, yes. Implicit conversion (of data pointers) TO void *, or
qualified void * where applicable, is fine in both C and C++.

Of course the result of malloc is an example of 'from'.
If you write code and try to routinely compile it with both C and
C++ compilers you deserve whatever happens to you. The languages
are _different_. The multiple compilers is not normally useful
anyhow, since you can always compile C in such a manner as to be
linkable to C++, but not the reverse.

Yes (only as far as stated) and no.

Every C++ compiler/implementation is required to be link-compatible
with at least one C compiler/implementation for the same target; in
practice many (most?) implementations of C++ actually include the
related C compiler, often tied together so closely it's hard to tell
them apart. Thus you _can_ compile C to be compatible with a given
C++, by using the (or a) 'suitable' C; but it does not follow that
compilation of C by an arbitrary C compiler is compatible with a given
or even any C++. You do need to avoid some external-linkage names that
are reserved in/with C++ even though they would be allowed in plain C.
But in most if not all C environments there are anyway other (chunks
of) external names you must avoid, so this is a familiar problem.

Conversely, you can write C++ that uses extern-C linkage and is
restricted to C semantics in the interfaces, and IS guaranteed
linkable from the related C implementation(s). Although you may have
to use nondefault linking procedures such as manually specifying a C++
runtime, which normally the C++ implementation does for you.
Since this doesn't allow you quite the full range of C++, perhaps we
should call it (C+=1)-FLT_MIN . Well, perhaps not.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
F

Flash Gordon

David Thompson wrote, On 12/11/07 02:17:
FROM void*, yes. Implicit conversion (of data pointers) TO void *, or
qualified void * where applicable, is fine in both C and C++.

Of course the result of malloc is an example of 'from'.


Yes (only as far as stated) and no.

Every C++ compiler/implementation is required to be link-compatible
with at least one C compiler/implementation for the same target; in
practice many (most?) implementations of C++ actually include the
related C compiler, often tied together so closely it's hard to tell
them apart. Thus you _can_ compile C to be compatible with a given
C++, by using the (or a) 'suitable' C; but it does not follow that
compilation of C by an arbitrary C compiler is compatible with a given
or even any C++. You do need to avoid some external-linkage names that

<snip>

Note also that no C++ compiler is required to be link-compatible with
any other C++ compiler and no C compiler is required to be
link-compatible with any other C compiler. In face a number of C and C++
compilers have options which change the binary interface and thus break
compatibility with other code produced by the *same* compiler with
different options.
 
J

James Kuyper

David said:
....

Yes (only as far as stated) and no.

Every C++ compiler/implementation is required to be link-compatible
with at least one C compiler/implementation for the same target; in

Every C++ compiler is required to support "C" linkage. I don't believe
the C++ standard actually specifies that there must be a C compiler it
can link with. I believe a C++ implementation could be conforming even
if the only thing it could link with were other modules compiled by
itself in C++ mode. Declaring anything as having "C" linkage would be
pretty pointless on such an implementation, but it would be meaningful.
That's because "C" linkage affects the ways in which other code written
in C++ can use the thing so-declared.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top