How would you design C's replacement?

B

Ben Bacarisse

BartC said:
Fortran seems to have moved on a lot more than C has. Modern C syntax
doesn't look much different to 30 years ago. The glimpse I had of
modern Fortran was unrecognisable.

In fairness to C, Fortran did have further to move!
 
I

Ian Collins

The earlier you can catch an error, the better; compile time is better
than test time.

Only just if like me make == make test (or is that make = make test?)..
 
K

Keith Thompson

Rui Maciel said:
I don't believe you are wrong; quite the opposite, in fact. The only issue
I have is that if we consider that assembly code with macros is also
assembly code, as is assembly code which calls routines stored in a library,
then we accept that at least a certain amount of abstraction, one which
takes us away from specifying instructions and leads us to specify run-time
behaviour, is also compatible with the concept of an assembly language.
This is the grey territory I was referring to.

That's certainly not the impression you gave last time around.

An assembly language program with macros still specifies a particular
sequence of machine instructions *when you consider the program along
with the macro definitions*. As for calling library routines, the
assembly program still just specifies a CALL instruction (or whatever
the equivalent is). The behavior of that CALL instruction is up to the
library routine.

If I write a call to a library routine in C, the compiler can generate
whatever code it likes, as long as that code's behavior satisfies the
standard's requirements. That might well be a CALL instruction, or it
might be inline code that does what the CALL would have done.

If I write a call to a library function in assembly language, I expect
to see a CALL instruction in the generated code.
 
B

BGB

One could also design the language such that a pointer isn't strictly an
address (as pointers are typically implemented on most hardware).
Instead, a pointer could be the equivalent of:

struct pointer
{
void raw * base;
size_t size;
void raw * address;
};

(The "raw" keyword means the pointer is a raw address, and not this new
"pointer" thingy. User code would not be allowed to create such pointers.)

Then, any time pointer arithmetic is performed, bounds checking is
performed (what happens on under/overflow is TBD) and a new pointer is
created with the adjusted values. (The "++", "--", "+=", an "-="
operators don't create a new pointer. They just modify the current one.)

Note that the word was "possible", not "practical".

if you also add a type signature and an element size-step, then this
isn't too far from how pointers (and arrays) are implemented for my
script language.

actually, they are also heap-allocated dynamically-typed objects as
well, although they still obey value-type semantics.

granted, yes, this isn't exactly the most efficient possible
implementation, but oh well...
 
B

BGB

On 5/2/2012 11:21 AM, Rui Maciel wrote:
[...]
If someone really needs some hand-holding with the assignment operator, a
macro could help. The following macro might do the trick:

#define SET(A,B) { A = B; }


I don't believe this sort of solution will ever be popular.

You forgot:

#define BEGIN {
#define END ;}
#define GETS_ASSIGNED_FROM =
#define IS_EQUAL_TO ==

#define SET(A,B) BEGIN A GETS_ASSIGNED_FROM B END

and thus begins "C: The Quest for COBOL"...
 
M

Michael Angelo Ravera

...whilst still providing reasonable HLL capabilities. C's current survivability is more related to its ubiquitousness than too its original design goals.


never quite understood what "fake assembly language" was? What is it you want that FAL can provide but other syntax can't?

<snip>

Not so much "Can't" but "Doesn't".

Examples:
Divide capturing both the quotient and the remainder in registers.
Move capturing both the next destination address and the next source address in registers.
Swaping the contents of some memory location with the Accumulator or top of the stack.

You could easily invent syntaxes for each of these, but they would end up looking a great deal like assembly language.

Virtually every processor that has a divide instruction has both the quotient and remainder available at one go, but it is hard to do this efficiently without resorting to assembly language (either directly or indirectly).
 
M

Malcolm McLean

בת×ריך ×™×•× ×—×ž×™×©×™, 3 במ××™ 2012 09:14:48 UTC+1, מ×ת (e-mail address removed):
On Monday, April 30, 2012 9:01:17 AM UTC+1, Malcolm McLean wrote:

even C++ doesn't do SQL and graphics! Whose graphics would you standardize on?
Im not sure I want an RDMS on my toaster.
You need three levels, non-hosted environments (toasters), non-graphical hosted environments (file servers, supercomputers), and graphical hosted environments (phones, the device you are using right now).

It doesn't really matter whose graphics you standardise on. You need to be able to open a window (the window might be constrained to be always the same size as the screen), and to write a pixel to an x,y co-ordinate. The problem is 1) that colour-indexed displays are still hanging around 2) there's still an efficiency problem, often you need to write several pixels in native format in one go, for performance reasons.
On top of those two basic functions you can implement Open GL, GUIs like Qt, or whatever you want
 
B

BGB

Not so much "Can't" but "Doesn't".

Examples:
Divide capturing both the quotient and the remainder in registers.
Move capturing both the next destination address and the next source address in registers.
Swaping the contents of some memory location with the Accumulator or top of the stack.

You could easily invent syntaxes for each of these, but they would end up looking a great deal like assembly language.

Virtually every processor that has a divide instruction has both the quotient and remainder available at one go, but it is hard to do this efficiently without resorting to assembly language (either directly or indirectly).

most of these could be handled either by functions or by compiler
intrinsics (which in turn look like functions).


the problem here is that often many such intrinsics in turn depend on:
which compiler is in use;
the target architecture;
the operating mode and compiler flags of said architecture;
....

this in turn often makes using compiler intrinsics nearly as dangerous
(portability-wise) as using ASM, although it is often still a little
cleaner than resorting to either raw ASM or inline ASM.


an alternative would be requiring the intrinsics to always be available
(even if they would need to be emulated), but this is much less commonly
done.

a major example of these sorts of intrinsics being the vector/SIMD
extensions for MSVC and GCC, ...


IMO, it is "cleaner" to create a higher-level wrapper interface, which
may in turn either use intrinsics if available, or revert to good old
"normal logic code" otherwise.

for example, a wrapper can be written for doing vector and matrix math,
which may used SIMD, or may just revert to scalar operations, depending
on the availability of SIMD intrinsics.
 
B

Ben Pfaff

Michael Angelo Ravera said:
Virtually every processor that has a divide instruction has
both the quotient and remainder available at one go, but it is
hard to do this efficiently without resorting to assembly
language (either directly or indirectly).

This is one rationale for the *div family of functions:

7.20.6.2 The div, ldiv, and lldiv functions

Because C89 had implementation-defined semantics for
division of signed integers when negative operands were
involved, div and ldiv, and lldiv in C9X, were invented to
provide well- specified semantics for signed integer
division and remainder operations. The semantics were
adopted to be the same as in Fortran. Since these
functions return both the quotient and the remainder, they
also serve as a convenient way of efficiently modeling
underlying hardware that computes both results as part of
the same operation.

....

Now that C9X requires similar semantics for the division
operator, the main reason for new programs to use div, ldiv
or lldiv is to simultaneously obtain quotient and
remainder.
 
M

Michael Angelo Ravera

These are simply functions that MIGHT be implemented efficiently. They are useful, but not for such things as implementing an efficient multi-precision divide (doing 256-bit integers on a 64-bit machine, for instance).

Also, notice that no one has said anything about doing anything like this for data moves. In theory the same thing would work:
addrpair movem (addrpair ap, size_t move_size);
but pairs of addresses are often too large to put into an atomic unit that can be returned by functions.
 
J

James Kuyper

These are simply functions that MIGHT be implemented efficiently.

The entire language MIGHT be implemented efficiently. If the possibility
of inefficient implementation is unacceptable to you, C isn't for you,
nor is any other HLL. A fully conforming implementation of C can be
arbitrarily inefficient. The only way to ensure what you consider
acceptable efficiency is to do it yourself, in assembly. Of course, that
assumes that you know how to create highly efficient assembler.
 
M

Malcolm McLean

בת×ריך ×™×•× ×©× ×™,7 במ××™ 2012 12:18:14 UTC+1, מ×ת James Kuyper:
The entire language MIGHT be implemented efficiently. If the possibility
of inefficient implementation is unacceptable to you, C isn't for you,
nor is any other HLL. A fully conforming implementation of C can be
arbitrarily inefficient. The only way to ensure what you consider
acceptable efficiency is to do it yourself, in assembly. Of course, that
assumes that you know how to create highly efficient assembler.
You're entitled to assume that, given two arbitrary pointers to nul-terminated sequences of arbitrary length, strcmp() is the most efficient way of comparing them.
But of course it might not be the most efficient way of comparing two strings for equality. By constraining strings to be 64-bit aligned, and by always padding the terminating nul to make up a round figure of 8 bytes, on a 64-bit machine we can probably implement a strcmp() which is eight times faster. High level language X might well do that. C can't do that because strcmp("fred" + 2, "ed") has to be valid.
Then of course much of the time we simply want a binary yes / no. So if we store the string length, then most of the time we can get the answer in a single machine instruction. Algorithmic improvements generally beat micro-optimisation.

But it's unlikely that an 8 times speed up from string compares is really worth having. If it is worth having, you can always implement your own string type in C, and you probably don't even need to resort to the inline assembler to make it efficient. In practice, language X is almost always slower.The string compares might be faster, by things will happen like every string being allocated in dynamic memory, which will slow it down it the other functions.
 
J

James Kuyper

בת×ריך ×™×•× ×©× ×™, 7 במ××™ 2012 12:18:14 UTC+1, מ×ת James Kuyper:
You're entitled to assume that, given two arbitrary pointers to nul-terminated sequences of arbitrary length, strcmp() is the most efficient way of comparing them.

That may be true, but if so, your entitlement is not derived from the C
standard, which says nothing about such matters. You haven't specified
whence your sense of entitlement derives, but the most plausible
argument I can think of for your assumption applies equally well to
div() being the most efficient way to simultaneously capture both the
quotient and the remainder.
 
B

Ben Pfaff

Malcolm McLean said:
you're entitled to assume that, given two arbitrary pointers to
nul-terminated sequences of arbitrary length, strcmp() is the
most efficient way of comparing them.

I wouldn't assume that. The author of strcmp() might have had
different criteria in mind. For example, he might have optimized
for small code, or for code that can be proved to be correct, or
for code that could be written quickly (if he was in a hurry).
 
Q

Quentin Pope

Le 30/04/12 20:25, (e-mail address removed) a écrit :

C is perfect?

Trigraphs included?

Now, come on...

The ignorant words of someone who hasn't spent any time using a 3270
terminal.
 
J

jacob navia

Le 09/05/12 23:06, Quentin Pope a écrit :
The ignorant words of someone who hasn't spent any time using a 3270
terminal.

I think you are representative of a class of people here:

1) Aggressive ("ignorant words")

2) Prejudices ("someone who hasn't spent any time in a 3270).
How do you know Mr? You have absolutely no idea what terminals I
have used. And yes, I have used a lot the 3270 in the eighties.

3) Outmoded. Yes, the 3270 is THE TERMINAL in use today. That is why
ALL C USERS must use trigraphs whether they need them or not!

4) Always looking into the past, speaking about old machines and
disappearing (or non existent) hardware...
"Remember the 3270"? "Remember the CDC xxx"? Remember the good
old days?

ALL IN ONE: "Quentin Pope"
 
I

Ian Collins

Le 09/05/12 23:06, Quentin Pope a écrit :

I think you are representative of a class of people here:

1) Aggressive ("ignorant words")

2) Prejudices ("someone who hasn't spent any time in a 3270).
How do you know Mr? You have absolutely no idea what terminals I
have used. And yes, I have used a lot the 3270 in the eighties.

3) Outmoded. Yes, the 3270 is THE TERMINAL in use today. That is why
ALL C USERS must use trigraphs whether they need them or not!

4) Always looking into the past, speaking about old machines and
disappearing (or non existent) hardware...
"Remember the 3270"? "Remember the CDC xxx"? Remember the good
old days?

ALL IN ONE: "Quentin Pope"

A pretty decent summary!
 
K

Kenny McCormack

I think if you set out to design a replacement for C - that is, a C without
all the defects - you'd end up with something very close to D (from Walter
Bright). From what I've read, D is what C should have been.

That D hasn't taken the world by storm should tell us (all of us) something
about what the market thinks of the idea of a replacement for C.

--

Some of the more common characteristics of Asperger syndrome include:

* Inability to think in abstract ways (eg: puns, jokes, sarcasm, etc)
* Difficulties in empathising with others
* Problems with understanding another person's point of view
* Hampered conversational ability
* Problems with controlling feelings such as anger, depression
and anxiety
* Adherence to routines and schedules, and stress if expected routine
is disrupted
* Inability to manage appropriate social conduct
* Delayed understanding of sexual codes of conduct
* A narrow field of interests. For example a person with Asperger
syndrome may focus on learning all there is to know about
baseball statistics, politics or television shows.
* Anger and aggression when things do not happen as they want
* Sensitivity to criticism
* Eccentricity
* Behaviour varies from mildly unusual to quite aggressive
and difficult
 

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
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top