Has thought been given given to a cleaned up C? Possibly called C+.

  • Thread starter Casey Hawthorne
  • Start date
J

Jasen Betts

Richard said:
Casey said:
Peter Van Der Linden in "Expert C Programming - Deep C Secrets" 1994
and I imagine others have pointed out some of C's idiosyncrasies.
Has thought been given given to a cleaned up C? Possibly called C+.

According to Stroustrup [TC++PL, intro], the name "C+" has already been
taken, by a language unrelated to either C or C++.

I guessed the next one was going to be C flat.

there's already 2 different D-flats, so yeah. :)




--- news://freenews.netfront.net/ - complaints: (e-mail address removed) ---
 
N

Nick Keighley

Nick Keighley <[email protected]> writes:

[C and C++ are not compatible because new is a reserved word in C++]
From scratch, yes.  Most existing C code will need modifications, such
as casts for malloc() and renaming variables or functions called new and
delete (which are the most common conflicts).  The implicit "struct" /
"class" will get you in trouble if you're in the habit of typedefing
structs.

really? Why? I'll have to go digging but I'm pretty sure I've done
this.
 
D

Dag-Erling Smørgrav

Ian Collins said:
Dag-Erling Smørgrav said:
The implicit "struct" / "class" will get you in trouble [...]
Why?

C keeps struct names in a separate namespace, C++ doesn't. The simplest
example I can come up with is this, which is legal in C but not in C++:

struct s { int i; };
typedef int s;

C++ has an exception for typedefing a struct or class under its own
name, i.e. this is fine in both languages:

typedef struct s { int i; } s;

DES
 
B

Ben Bacarisse

jacob navia said:
I am not convinced of any application of operator overloading that is not
(1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

ALl others, like using + to "add" srings or << or >> to print stuff are
bad usages in my opinion.

What about a library for doing symbolic manipulation of expressions --
for example polynomials. Would you not want to define + as the
operation of addition on polynomials?
Of course it can't be avoided. And, as you
know, in C I can write:

int AddTwoIntegers(int a,int b)
{
return a/b;
}

You can write bad code in ANY language.

True, but the arguments against operator overloading don't just rely
on similar inappropriate usage. In some cases, finding the "matching"
function is non-trivial. Your implementation may be such that this
issue never arises. If so, it is big point to talk up.

<snip>
 
S

Stephen Sprunk

Ian Collins said:
Dag-Erling Smørgrav said:
The implicit "struct" / "class" will get you in trouble [...]

Why?

C keeps struct names in a separate namespace, C++ doesn't. The simplest
example I can come up with is this, which is legal in C but not in C++:

struct s { int i; };
typedef int s;

C++ has an exception for typedefing a struct or class under its own
name, i.e. this is fine in both languages:

typedef struct s { int i; } s;

.... and I suspect that exception was specifically added to C++ to
support compiling C code that uses that common idiom to work around C's
separate name space for structs.

S
 
D

Dag-Erling Smørgrav

Dag-Erling Smørgrav said:
C++ has an exception for typedefing a struct or class under its own
name, i.e. this is fine in both languages:

typedef struct s { int i; } s;

missing "but a no-op in C++"

DES
 
A

Andrew Poelstra

I think Jocob wants something that is "better" than C (and a bit
bigger) but not as monstrous as C++. I'm curious as to whether he can
do it.

I think the biggest missing feature of C is namespaces. If we had
namespaces it would be a lot easier to share (and reuse) libraries
because there'd be far less risk of name clashing.

Plus we would have to name everything something insane and confuse
the package name with the function name.

For example, if I were to use Jacob's library (whenever it is
"complete"), I might create a tree with

navia::avl_tree t1 = navia::new_avl_tree(/* whatever */);

Which is a little ugly, but if his was the only avl tree library
I could stick a

using navia::avl_tree*

at the top and be done with it.


As it stands, to avoid name clashes his avl tree functions might
need to be prefixed with navia_ (or something less self-serving
perhaps), which not only still has the potential for name clashing,
but also begs the question, is a "navia_list" a list of Navias
or a list from the Navia library. (Or a list used for some "navia"
widget, or maybe it means NAV for Intel Architecture, where NAV
could mean anything, or ...)
 
I

Ian Collins

Nick said:
I think Jocob wants something that is "better" than C (and a bit
bigger) but not as monstrous as C++. I'm curious as to whether he can
do it.

There was such a beast - Embedded C++ (EC++). It died due to lack of
vendor support and little developer interest. Sound familiar?
 
I

Ian Collins

Dag-Erling Smørgrav said:
Ian Collins said:
Dag-Erling Smørgrav said:
The implicit "struct" / "class" will get you in trouble [...]
Why?

C keeps struct names in a separate namespace, C++ doesn't. The simplest
example I can come up with is this, which is legal in C but not in C++:

struct s { int i; };
typedef int s;

C++ has an exception for typedefing a struct or class under its own
name, i.e. this is fine in both languages:

typedef struct s { int i; } s;

Fair enough. Although I'd class that as an obscure corner case.
 
F

Flash Gordon

jacob said:
Nick a écrit :

The advantages of a JIT is that you can translate on the fly code
generated to fit certain circumstances that change from invocation to
invocation.

<snip>

I understand the advantages of a JIT.
The only thing that operator overloading adds to the language is the
possibility
for the USER to add itsb own numeric types. Besides, if you do not
like that
feature, do not use it. The language stays the same otherwise.

The danger with operator overloading is that it lets the USER add their
own NON NUMERIC [I thought I'd try adopting your STYLE for a while, but
got out of BREATH fairly QUICKLY] types. Look how long it took C++ to
get << and >> for streams - about 10 seconds.

I am not convinced of any application of operator overloading that is not
(1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

You can't, however, restrict it to that without preventing doing things
like complex numbers using operator overloading.
ALl others, like using + to "add" srings

I don't mind + or . for string concatenation in other languages (C has
problems with this usage due to the need for memory allocation).
or << or >> to print stuff are
bad usages in my opinion.

I can see the logic of them, but I've not looked at the details of C++.
Of course it can't be avoided. And, as you
know, in C I can write:

int AddTwoIntegers(int a,int b)
{
return a/b;
}

You can write bad code in ANY language.

Yes. However, in C you at least know that + *is* addition.
Excuse me but the subject of this thread is:

Has thought been given given to a cleaned up C? Possibly called C+.

To me "cleaning up" suggests getting rid of the bad bits rather than
necessarily adding new features.
Those are minor incoveniences. Yes, they are bad for newcomers but
what is essential is the stuff that is bad for newcomers AND for
experienced users.

My experience is that operator overloading leads to confusion for
experienced users.
Mr Heathfield is an experienced C programmer. The fact that even he had
a bug with zero terminated strings makes obvious that it is NOT his
abilities as a programmer that are bad, but a tool that uses ERROR PRONE
construct.

I've seen experienced programmers make mistakes with counted strings, so
by your logic we should not use them either.
(If you do not like my STYLE, please tell me how to put
emphasis in *plain ascii* :) )

As you have just done above, with *stars*. Or /slashes/ where you might
otherwise have selected italics.
 
T

Thomas Richter

Lorenzo said:
What does it means "GUI-intensive" and why should java be better at
solving these kinds of problems?

Because it comes with a large, reasonable libray, and a complete
toolchain for doing that. It offers the right infrastructure for it.
Excluding subjective aesthetic
consideration on the resulting GUIs, I think some operations
"could" (but I'm unaware of recent changes so I could be wrong) be a bit
slower than an analogous C or C++ counterpart.

Certainly, but not that I would mind much for a GUI. I would mind for
number crunching, but that's again not a domain of Java. Probably C, but
maybe even (shudder) FORTRAN.

So long,
Thomas
 
T

Thomas Richter

Richard said:
The answer to this is that the standard could have environment
dependent sections. Thus the standard could say that IF the
environment supports a directory based file system then the
implementation provides the corresponding POSIX library.

Why would that add anything? I mean, there *is* already a standard for
that, namely POSIX. Why would adding that to the C standard as an
optional annex make C any better? You would be able to use the *same*
functions at systems you would have been able to use them before, and
for system that don't implement them, you wouldn't gain anything either.

It is only a naming issue, really.
Having a container library is a different kind of issue because
it isn't environment dependent. The standard could specify a
container library. The sticking point is what should it look
like.

There the sticking point is to make it useful enough in C. Of course you
can with a lot of casting, or in a non-generic way you could, or with
macros you could, but I would believe the solutions you could come up
with that deal only with the tools the language offer are either unsafe,
or ugly, or non-generic.

IMHO, not having that doesn't make C any worse. But probably not quite
the right tool for this kind of job. C *should* IMHO remain tiny and
simple, that's its strength, and I wouldn't want to loose that.

So long,
Thomas
 
N

Nick Keighley

Nick a écrit :

wow. awesome. No, I'm genuinely impressed.
I'm not so sure this is in the "spirit of C"
Doesn't it require that applications carry around a large runtime
system?

Have you heard of Greenspun's Tenth Rule...?

The danger with operator overloading is that it lets the USER add their
own NON NUMERIC [I thought I'd try adopting your STYLE for a while, but
got out of BREATH fairly QUICKLY] types.  Look how long it took C++ to
get << and >> for streams - about 10 seconds.

I am not convinced of any application of operator overloading that is not
(1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

ALl others, like using + to "add" srings or << or >> to print stuff are
bad usages in my opinion. Of course it can't be avoided. And, as you
know, in C I can write:

how about smart pointers or Functors (over loading the () operator)?

[...] (If you do not like my STYLE, please tell me how to put
emphasis in *plain ascii* :) )

"if you do not like my <em>style</em>"
<smiley>
 
N

Nick Keighley

jacob navia schrieb:
There is no way in C to return a list of the files in a directory.
[...]
Not in C, but in POSIX, which is implemented by most C compilers.

really? Do you have figures?

but C++ has a Boost library
The answer to this is that the standard could have environment
dependent sections.  Thus the standard could say that IF the
environment supports a directory based file system then the
implementation provides the corresponding POSIX library.

or something more abstract. Why should the Windows (and maybe VMS)
people be left out?

<snip>
 
N

Nick Keighley

Nick Keighley wrote:

There was such a beast - Embedded C++ (EC++).  It died due to lack of
vendor support and little developer interest.  Sound familiar?

if memory serves me they removed exceptions, templates (eek! no more
STL!) and (less sure here) multiple inheritance. Seemed at pretty good
idea to me at the time. Shows how much I know!

<google>
they also proposed removing:-
virtual base classes (!! is it still an OO language after that?)
RTTI (ok)
new cast syntax (always seemed mostly harmless to me (dynmaic cast
being the non-harmless bit))
mutable (why?)
namespaces

those features were either perceived to be slow, difficult to
implement or recently introduced (and hence not universally
supported). It didn't help that Bjarne Stroustrup showed no enthusiasm
for subsets. And my reaction indicates that everyone who wants to
subset C++ (or likely any other language) has their own ideas as to
what is "core" and what is over-head. And mine changed over time.
 
J

jacob navia

Ben Bacarisse a écrit :
jacob navia said:
I am not convinced of any application of operator overloading that is not
(1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

ALl others, like using + to "add" srings or << or >> to print stuff are
bad usages in my opinion.

What about a library for doing symbolic manipulation of expressions --
for example polynomials. Would you not want to define + as the
operation of addition on polynomials?

In general we should have

a+b <--> b+a
a*b <--> b*a

a>b && b>c <--> a>c

etc

If your operations doesn't fulfill those it is better to use
a plain function with an explicit name.

Besides, operator overloading allows you infix notation.
Do you call your operation very often? If not, it is better
to use a plain function call.
 
B

bartc

jacob said:
Ben Bacarisse a écrit :
jacob navia said:
I am not convinced of any application of operator overloading that
is not (1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

ALl others, like using + to "add" srings or << or >> to print stuff
are bad usages in my opinion.

What about a library for doing symbolic manipulation of expressions
-- for example polynomials. Would you not want to define + as the
operation of addition on polynomials?

In general we should have

a+b <--> b+a
a*b <--> b*a

What do you have against a-b and a/b?
 
B

bartc

bartc said:
That's exactly what I was thinking, when I first looked at using C
around '92**. Surely someone would have got round to tidying up the
language by then?

Tidying up of C Language

For someone taking a fresh look at C, and who doesn't care too much
about it's history or compatibility with existing code, these are a
few things that might stand out.

I'm not necessarily providing any fixes here, just pointing out areas that
might cause raised eyebrows:

Standard Headers

There are a dozen or two of these, and you have to keep including or
unincluding them as the contents of the file change.

Why not just take the inclusion of all of them as read? (There are
all sorts of reasons why it's kept like this, but remember a
newcomer to the language doesn't care about these reasons, only that
they are a right pain.)

'Header' Files

A misnomer for ordinary include files. Someone used to Import
statements for example might expect the contents of header files
to exist in a separate scope from the module being compiled.

(Although a proper treatment of header files might be difficult
without introducing module namespaces too.)

Type Qualifiers

Things such as long long unsigned int. This just looks silly (and I
know the idea came from Algol-68, I thought it silly there too).

Macros can be used to tame these to some extent, but are not
standardised (?)

Type Declarations

These are C's famous convoluted inside-out declarations. I've
already suggested a left-to-right alternative (which might just
co-exist with the old scheme)

Struct Namespace

Just a cause of confusion. Just let a struct name be equivalent to
a typedef name.

Numeric Literals

Who would have guessed that 0123 is an octal number? Get rid of that
notation, and introduce 8x123 if anyone is still interested.

And there should be a notation for binary literals, perhaps 2x11011.

And those strange suffixes you sometimes see: LU, LLU and so on,
are they really necessary? Why can't the type of the constant be
automatic?

Sizeof Operator

This just gives the number of bytes in a type (or the type of an
expression). That's fine, but what about getting the number of
elements of an array? Ie. without bothering having to divide the
bytes in the entire array by the bytes in one element...

Type Limits

These is where you start seeing names such as USHRT_MAX and
LLONG_MIN (all tacky abbreviations we are constantly told to avoid
as macros and typedefs), and where you start wondering, is there a
Better Way?

(Such as, perhaps, long.max or signed char'min, which together with
a set of standardised short type names would tidy things up
considerably.)

Format String Codes

These seem innocuous enough at first, sucgh as %d and %f. Then you
start to see %lu, %lld, %zu (or whatever), etc. etc.

(Strange how this long/long long business seems to be all-
pervading.)

And this point you might think: the format string is usually a
string literal, the compiler knows what types are being supplied to
printf() or whatever, so why bother having to specify each format in
such excruciating detail (since as as soon as a type changes, you
might have to revise hundreds of such formats)?

So why not let the compiler do the work? (I think I suggested %?
format once as an automatic format specifier)

Operators

A power operator is missing (I think because no-one can decide what
to use, since * is heavily involved with pointers).

The << and >> operators have a strange precedence (they effectively
multiply and divide, so should be the same as * and /)

Switch Statement

It should not be necessary to use break to terminate every case
statement. (And there's the problem that break cannot then be used
to escape from a loop).

Case expressions should be able to use ranges and commas:

case 1,2,3,5..7,8:

instead of:

case 1: case 2: case 3: case 5: case 6: case 7: case 8:

No excuses!

And Switch statements are very strange in that the case statements
do not form a normal block scope, so that you can have a case label
buried deep inside an embedded if statement or a loop! This is just
too weird to have in a serious language.

For Statement

This is a funny, but useful, variation, of a loop statement, but is
not a For statement as normally understood. A streamlined 'proper'
For statement would be handy (but is awkward to fit into C's zero-
based philosophy).

Multi-level Breaks from Loops

This would save a *lot* of mucking about with code. Just *have*
them!

Named Constants

Ie. what someone might expect when writing const int x=1000; x is
variable not an alias for 1000.

Given that const really means read-only, there is no proper way of
assigning a name to a literal, other than workarounds using #define
and enum, both with their own restrictions.

Arrays

Array handling is ... different. However I don't have suggestions
to fix that, without completely changing the language.

Name Scoping

As I understand it, function names, and variable names declared
outside of functions, are always exported unless some attribute
(static?) is used.

I don't think this is what one would expect (ie. names are normally
private unless explicitly exported). The way C works now seems just
a little too casual.

Text and Binary File Modes

No comments needed...

Compiler Attributes

When you look at actual header files they always seem to be full of
cr*p like this (and often a lot worse):

_CRTIMP __p_sig_fn_t __cdecl __MINGW_NOTHROW signal(int, __p_sig_fn_t);

all full of ad-hoc non-portable extensions specially designed to
make declarations completely incomprehensible.

Whatever it is these attributes are supposed to do, why not just
standardise them?

System Naming Schemes

The mixing of upper and lower case, and underlines (with a penchant
for running one, two and perhaps even three of them together) makes
for some rather ugly-looking system names.

So you have int, char, double, and ... _Bool! Or uint_least32_t.

This hardly makes for elegant, readable code. Somehow those long,
sprawling lists of such names you see in the C standard doesn't
quite seem the way to go.


Well, that's about all I could think of before breakfast. I've tried to
leave out personal preferences as that would have made it several
times the size.

And I've mainly concentrated on syntax...
 
B

Ben Bacarisse

jacob navia said:
Ben Bacarisse a écrit :
jacob navia said:
I am not convinced of any application of operator overloading that is not
(1) Done with new numeric types
(2) Done with access to containers (overloading [ ] )

ALl others, like using + to "add" srings or << or >> to print stuff are
bad usages in my opinion.

What about a library for doing symbolic manipulation of expressions --
for example polynomials. Would you not want to define + as the
operation of addition on polynomials?

In general we should have

a+b <--> b+a
a*b <--> b*a

a>b && b>c <--> a>c

etc

If your operations doesn't fulfill those it is better to use
a plain function with an explicit name.

They do. I was just giving an example that seems reasonable to me but
was ruled out by your "all others ... are bad usages" comment.

<snip>
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top