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...