Is C99 the final C?

A

Arthur J. O'Dwyer

Simon Biber wrote: [I wrote:]
Oh, and just for kicks, note that the &&& operator
would break some [pathological] C code.

Like this:
int a = 1, b, *p = &b;
if(a != 0 &&& b == p)
{
printf("a is non-zero and the address of b is equal to p\n");
}

True, but at least this wouldn't go unnoticed under hypothetical &&&
semantics, given that the expression "b==p" isn't valid.

Change "==p" to "==0", or just remove it altogether, to get
essentially the example of which I was thinking. As I said,
pathological -- but possible. :)

-Arthur
 
G

glen herrmannsfeldt

Someone said:
in comp.lang.c i read:
yes. (cf the pl/i standard)

There has been a long discussion cross posted between comp.lang.fortran
and comp.lang.pl1, started by a troll, over which language is better.

Fortran has changed many times over the years, and now has many of the
features that PL/I started with in the 1960's. PL/I has changed a
little of the years, but the changes are pretty small. Partly because
the demand for changed is small, but also because they got a reasonable
number of things right.

OK, to make this a little bit on topic, one of the questions from the
Fortran troll had to do with doing C like pointer operations, choosing
between two strings by assigning a pointer to the selected string to a
pointer variable, and then printing the desired string.

As I had never done pointer variables in PL/I, it seemed like an
interesting challenge. It turns out PL/I pointers can't point to string
constants, but they can point to initialized string variables. (This
removes the possibility of changing constants.) PL/I pointer variables
are more suited to operations related to linked lists than to many of
the uses that C uses them for.

With all those features, why isn't it more popular today? One reason
might be that it was ahead of its time. The first PL/I compiler was
required to run in 44K (64K machine, 20K OS) while compiling a language
significantly more complex than C. There was a significant amount of
run-time overhead needed to support many of those features that other
languages didn't need. (Fortran statically allocated all variables, for
example.)

It might be that many of the additions in C99 already existed in the
first PL/I standard. Complex variables are one example.

I would say that a language that was designed with plans for future
machines, instead of just matching existing machines, is more likely to
last without needing major changes.

-- glen
 
S

Sidney Cadot

Arthur said:
Simon Biber wrote:

[I wrote:]
Oh, and just for kicks, note that the &&& operator
would break some [pathological] C code.

Like this:
int a = 1, b, *p = &b;
if(a != 0 &&& b == p)
{
printf("a is non-zero and the address of b is equal to p\n");
}

True, but at least this wouldn't go unnoticed under hypothetical &&&
semantics, given that the expression "b==p" isn't valid.


Change "==p" to "==0", or just remove it altogether, to get
essentially the example of which I was thinking. As I said,
pathological -- but possible. :)

Ok. I was thinking for a moment that since "&b==0" reduces to false, and
since "&b" (as a truth value) reduces to true, something clever was
going to happen to the entire expression but it isn't.

However: there is precedent for changing the semantics of pathalogically
weird C code with the C89 -> C99 transition, with respect to the
introduction of double-slash comments. So I don't see how this would,
per se, prevent &&& from being introduced as an operator, despite your
keen observation.

Best regards, Sidney
 
S

Sidney Cadot

xarax said:
Not forbid, just a warning when the compiler notices that
the field offset is improperly aligned. Taking the address
may imply truncation of low-order bits and such when applied
to types with implicit alignment (depending on implementation),
so you want a warning when the generated pointer may not work
the same as a properly aligned item. If the field in the packed
structure just happens to be aligned properly, then fine (no
warning).

The problem with this is typical use of packed structures. Suppose
you're reading a binary file; at some point in this file, there's data
described by the packed structure.

While e.g. a double field may be properly aligned relative to the start
of the struct, it may no longer be properly aligned in memory relative
to the start of the chunk of bytes that we want to use the packed struct
to describe.


Simple example:

packed struct DStruct {
double x;
};

void f(double *arg);

unsigned char *x; (properly malloced, and containing the contents of the
binary file.)

Now I know that, there's 17 bytes of garbage at the start, then there's
a DStruct:

DStruct *dp = (struct DStruct *)(x+17);

If I now do:

f(&dp->x);

This may now fail because of improper alignement of the double.

Best regards,

Sidney
 
S

Sidney Cadot

Mark said:
That was why I suggested something other than enum. I'm not sure what
else the person who said he wanted enums to be more special might have
meant.

That would have been me. I was aiming for about the same status for
'enum' types as enumeration types have in Pascal. However, in C you can
of course assign definite integer values to members of an enum,
including duplicates - this complicates matters considerably.

I guess the only thing that could be done without breaking too much code
is mandating a compiler diagnostic on implicit conversion of an enum
value to an int value. Personally, I think that would be a good idea.

Best regards,

Sidney
 
C

Chris Torek

... My personal wish-list [for some future C standard] would include
(in no particular order):

[numerous items snipped]
* triple-&& and triple-|| operators: &&& and ||| with semantics
like the 'and' and 'or' operators in python:

a &&& b ---> if (a) then b else a
a ||| b ---> if (a) then a else b

(I think this is brilliant, and actually useful sometimes).

Besides the syntactic shift (from being parsed as "&& &b" today),
I think it is worth pointing out that if "a" is false, it must compare
equal to 0; so assuming "a &&& b" means "if a then b else a", it
also means "if a then b else 0", which can be expressed today as
"a ? b : 0".

(GCC offers "a ||| b" as "a ?: b", which means "a ? a : b" without
evaluating "a" twice.)
* a way to "bitwise invert" a variable without actually
assigning, complementing "&=", "|=", and friends.

The expression "x = ~x" can always be transformed into "x ^= ~0U",
although the constant may need to be written as 0UL, 0ULL,
(uintmax_t)0, or some such. (Using ^= ~(uintmax_t)0 probably
always works, but probably draws warnings on some compilers.)
* 'min' and 'max' operators (following gcc: ?< and ?>)

It is also worth noting that Dennis Ritchie's early C compiler(s)
*had* min and max operators, spelled \/ and /\ respectively. They
were dropped, most likely from lack of use.

Someone else asked (further down in the thread) whether some CPUs
might have "min" and "max" instructions. I have never seen precisely
this myself, but many architectures have "synthetic" (and branchless)
min/max sequences -- usually involving the carry bit (many CPUs)
or "set if less than" instructions (MIPS) or the like -- and even
the x86 now has conditional-move. GCC will generate these for the
branch-ful "a < b ? a : b" sequence, e.g.:

int imin(int a, int b) { return a < b ? a : b; }

compiles to, e.g.:

cmpl %eax, %ecx
cmovle %ecx, %eax

when gcc is given the right options (-msse). (V9 sparc also has
conditional move, and ARM has conditional *everything*. :) )
 
G

goose

Michael B. said:
I was just thinking about this, specifically wondering if there's any
features that the C specification currently lacks, and which may be
included in some future standardization.

Of course, I speak only of features in the spirit of C; something like
object-orientation, though a nice feature, does not belong in C.
Something like being able to #define a #define would be very handy,
though, e.g:

#define DECLARE_FOO(bar) #define FOO_bar_SOMETHING \
#define FOO_bar_SOMETHING_ELSE

whats wrong with
#define DECLARE_FOO(bar) FOO_ ##bar## _SOMETHING_ELSE

(I assume you wanted to use "bar" as an argument to the
first macro, right ?)

I haven't yet come across a good reason for #defining a new
#define.
I'm not sure whether the features of cpp are even included in the C
standard though

they are.
(and GCC has definitely taken quite a nonstandard approach
with regards to certain token expansions and whatnot), but that's one area
of improvement I see.

I would also like to see something along the lines of C++ templating,
except without the really kludgy implementation that the C++ folks decided
to go to ( and without the OOP ).

the actual templating support in C++ is done, imho, fairly well.
... Mike pauses for the sound of a thousand *plonks*

Templates save a lot of time when it comes to commonly-used data
structures, and as they are entirely implemented at compile-time and don't
include, by their definition, OOP (although they can be well suited to
it), I think they would be a nice addition and in the spirit of C.

I suppose so, as long as its done carfully enough that it:
a) doesn't break existing code.
b) is different enough in syntax to C++ so that
idiots who use the language "C/C++" will catch a clue.
having it compilable by a C++ compiler encourages
people to write code that will compile on both C and
C++ compilers cleanly.
Your thoughts? I'm sure there's some vitriol coming my way but I'm
prepared 8)

<grin> are you sure ?

goose,
 
D

Dan Pop

In said:
oops, advance it in comp.std.c rather than here.

It doesn't make any difference where you advance it: it will get ignored,
anyway.

If you want to promote an idea, either become a committee member or
convince one committee member that it's worth promoting it.

Dan
 
D

Dan Pop

In said:
Along the same lines, and probably in heavier use than PL/I today,
are Pascal (ISO 7185) and Extended Pascal (ISO 10206).

Which conforming implementations of ISO 7185 and ISO 10206 are in current
use today?

Dan
 
D

Dan Pop

In said:
'long' might be a better choice
for when you need an exactly 32-bit integer type.

Nope. long should be a better choice for when you need a 64-bit integer
type. The only unwasteful type assignation for the usual processors
currently used in hosted implementations is:

8-bit: char
16-bit: short
32-bit: int
64-bit: long

and there are C89 implementations that do the integral types this way.
No need for a long long at all.

Having int as an "alias" for either short or long was a historical
mistake that should have been exposed and corrected long ago. The C
standards keep blessing it, instead...

Dan
 
D

Dan Pop

In said:
Arthur said:
On Sun, 30 Nov 2003, Sidney Cadot wrote:

Michael B. wrote:
There's always some things that could be improved of course. My
personal wish-list would include (in no particular order):

* mandatory support for fixed-width integers (in C99, this is
optional).

This would make some platforms incompatible with C; up to this
point, C has never [to my knowledge] *required* any fixed-width
data types. How about those 9-bit-byte mainframes everyone likes
to bring up?

I think their main raison-d'etre at the moment is as serving as
counter-examples in c.l.c discussions. Perhaps it is time, in the next
C version, to mandate that CHAR_BIT==8. I don't know.

Definitely not. CHAR_BIT==9 may be rare these days, but CHAR_BIT==16 is
not once you start looking at DSP processors which often don't have the
ability to access less that 16 bits (or or) in one operation.

But those are used in freestanding implementations only, and we ignore
such implementations by default, here.

Dan
 
D

Dan Pop

In said:
I was just thinking about this, specifically wondering if there's any
features that the C specification currently lacks, and which may be
included in some future standardization.

I would happily trade all the new stuff in C99 for all the sensible GNU C
extensions to C89. The resulting standard would be widely implemented
from day one and a lot more useful than a widely implemented C99 would
ever hope to be.

Dan
 
D

Dan Pop

In said:
I agree wholly on the // part, that's a C++-ism that I'd rather see
deprecated in the next standard ;-)

C++ didn't invent // comments, it merely inherited them from C's ancestor,
B. One could argue that they belonged to C since day one ;-)

Dan
 
P

pete

Mark said:
There's nothing that requires long to be exactly 32 bits any more
than int. Both would be equally nonportable assumptions.

A type which is guaranteed to have at least 32 bits, is a better choice
than one which isn't guaranteed to have at least 32 bits,
for when you need an exactly 32-bit integer type.
 
P

pete

Dan said:
Nope. long should be a better choice for when you need a 64-bit
integer type.
The only unwasteful type assignation for the usual processors
currently used in hosted implementations is:

8-bit: char
16-bit: short
32-bit: int
64-bit: long

and there are C89 implementations that do the integral types this way.
No need for a long long at all.

Having int as an "alias" for either short or long was a historical
mistake that should have been exposed and corrected long ago. The C
standards keep blessing it, instead...

That might be the case, if you're talking about implementing C,
but I beleive that Arthur J. O'Dwyer,
was talking about the the C programmer's choice
for when it comes to choosing a type, while writing C code.

I use long to implement psuedorandom number generators
which generate 32 bit values, portably.
I can't do that with int.
 
R

Randy Howard

I don't like it either, but it would be nice to have a well-defined
way to get packed structs on any implementation. Obviously, because
of the large performance hit, you would only use the packed attribute
where it was absolutely necessary.

Hmm, something like
#pack n
and
#pack default
to reset to whatever the compiler normally does?
 
R

Randy Howard

I use gcc, mainly, but the software's users use a variety of systems
(mostly win32, Linux, Sun, HP, AIX, Irix, ...), and I cannot rely on
anything better than a C89 compiler to be available.

If that's the case, then it hardly seems likely that the C0X extensions
which may or may not help you out will be any more useful than any of
the stuff in C99? :)

Don't get me wrong, this is an interesting thread, but regardless of
the outcome, one has to wonder how many current C programmers will
live long enough to see C99 be available "practically everywhere",
much less whatever comes after it.
 
C

Chris Hills

James Kuyper said:
No - I think that &&& and ||| would be so rarely used that their
meanings would become trivia questions.


see Rule 36 of the MISTRAY-C C coding standard at
Http://mistray-c.phaedsys.org

It is the antidote to MISRA-C and should raise a smile or three.

I am looking for some code examples to illustrate some of the rules.

regards
Chris

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/\
/\/\/ (e-mail address removed) www.phaedsys.org \/\/
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
 
J

James Kuyper

Sidney Cadot said:
Arthur said:
The last statement I do not understand. Care to elaborate?


const int foo = 5;
char arr[foo];

Legal C++ (because in C++, const objects are really "constant"),
but illegal C (because 'foo' is an object whose value needn't
be stored [or even computed] at compile time).

This is legal at least in C99, and I think also in C89 (at least my gcc
doesn't even warn on it).

That's because C99 now allows variable-length arrays, so an integer
constant expression is no longer required in that context. However,
they were required in C89 in this context, so if a compiler fails to
issue a diagnostic, it isn't a conforming implementation of C89. All
of the following uses of foo except the one that is marked are still
illegal in C99, because they still require integer constant
expressions:

struct bf_holder{
int bit_field:foo;
} x[foo+1] = // Only legal use of foo in this section.
{[foo] = {10}}; // Subscript for designated initializer

enum {enumeration_value=foo};

switch(x[0].bit_field)
{
case foo:
}

struct bf_holder *p=x+foo;
 

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
474,159
Messages
2,570,879
Members
47,416
Latest member
LionelQ387

Latest Threads

Top