Ian Collins said:
Tim said:
Ian Collins said:
Tim Rentsch wrote:
An uncharitable view of your opinion is that it is simply
disguised chauvinism for the C++ way of doing things. Do you
have any arguments to offer for the merits of some of these
proposed new features that don't reference C++ but are able to
stand on their own?
There are number of C++11 additions that would improve and stand alone
in C in similar ways to C++, some examples: [examples snipped]
None of these are particularity radical, but they would make
programmer's life just that little bit easier.
Two comments:
1. I don't see any argument being offered other than "proof by
assertion".
One could say the same thing to the proponent of round wheels in
a square world.
And appropriately so, if all the proponent were offering consisted
of simply asserting that round wheels are an improvement.
The examples I cited were added to C++ to make
life easier for the programmer in use cases equally applicable to
a C programmer.
There are at least three things wrong with this statement. One,
saying they were added to make life easier for the programmer
doesn't mean they actually do so. Two, my question asked for
arguments that don't reference C++, yet your comments have been
made in a context which assumes C++ knowledge, both about the
language and about the arguments made in support of its new
features. Three, it is false -- in at least some of the cases
mentioned, the value proposition for the feature in question
depends on other parts of C++ that don't apply in C.
They are features I've embraced and miss when using older tools.
Saying you like them doesn't present a compelling argument. More
generally, listing a new feature and saying that in circumstance
X there is value having said feature available doesn't present a
compelling argument. As far as C goes, saying a new feature has
been embraced by the C++ community and adopted into C++ doesn't
present a compelling argument. If you (or someone else) can't
or won't present a compelling argument for a proposed addition
to C, in the context that the ISO C group operates, then we may
expect the proposed addition will be rejected, and rightly so.
In my previous response I gave only a summary reaction, and now I
think that wasn't the right thing to do, mainly for the reason
that your comments (and also you) deserve more consideration. So
let me try to remedy that now:
There are number of C++11 additions that would improve and stand
alone in C in similar ways to C++, some examples:
Static (compile-time) assertions. Yes you can do much the same
with the preprocessor, but there are limits and I believe
static_assert makes the conditions clearer as programme or
function preconditions. They are also more concise.
You assert there are limits but you don't say what they are.
You assert static_assert is more concise, but you don't say
more concise than what. If a macro STATIC_ASSERT is defined,
and used to accomplish static assertions, neither form is
more concise than the other.
I don't believe static_assert( condition, string ) is any
more clear than STATIC_ASSERT( condition, string ). Or we
could (in C) #define static_assert(c,s) ..., in which case
there is no reading difference between the language feature
and the macro call.
It is well known how to define a macro like STATIC_ASSERT even
in C90, and AFAIK its only downside is the error message out of
the compiler probably disguises the nature of the problem. Bad
cosmetically, but not really important in practice if the error
message gets you to the source line that has the assertion. The
upside is the macro form can be used in C99 and C90 (we may want
to define it differently in C11, to use _Static_assert, but we
can still use the macro). Some people just don't like macros
and want to expunge them at almost any cost, but having that
reaction doesn't offer a compelling argument as far as C goes.
I have to partly take back what I said above. It's hard to
write a STATIC_ASSERT that also works in the context of struct
member declarations, which _Static_assert allows. In practice
I think there is almost no value in being able to do static
assertions inside struct (or union) definitions;
Initialisations preventing narrowing. Removes another source of
unexpected behaviour.
You're implicitly asserting several things: one, this situation
happens fairly often; two, the cost when it does happen is high
(either because finding it is expensive on the average or because
it is likely to remain undetected); three, that putting such a
rule in the language is better than other possible alternatives.
To these assertions I say: one, if you want to assert this you
should be prepared with data to back it up; two, as it is a
known class of problem, and highly localized, surely there simple
coding practices that would suffice to find such problems
cheaply; and three, a better way to do this is with a compiler
warning or an external code analysis tool (with lint being the
obvious least common denomimnator example). Any language feature
that adds no expressive power but only warnings/errors is in
most cases better cast (no pun intended) as an option in a
source analysis tool (eg, compiler warning options).
General compile time constants with constexpr. This would be
particularly useful in the embedded world were you want to
minimise RAM use.
All you do is assert that it's useful, along with the other
implicit assertions (see above). For the sake of discussion let's
grant the given explicit assertion -- we still haven't got an
argument that's even plausibly compelling until the questions of
how often the situation occurs, how much value does the proposed
feature add when it does occur, and how does the proposed feature
compare to alternatives, are considered. Also for this feature
in particular it's important to consider the language complexity
cost, which is definitely non-trivial here.
nullptr. Removes another source of unexpected behaviour.
Again, all you're doing is asserting (including the implicit
assertions listed above). Furthermore, in C++ nullptr provides
value because C++ has a different rule for how 'void *' is
treated. In C, just '#define nullptr ((void*)0)' works fine
(for those people who feel a need to do so).
Raw string literals. Removes another potential source of
unexpected behaviour and hard to read code (how many slashes
do I need?).
The usual sorts of assertions, and little else. Here are some
problems: one, the weighted benefit is very close to zero; two,
the cost is non-trivial, not because of compilers but because of
all the other source processing tools that do C-level lexing, and
there are lots of those; three, alternatives are cheap and easy.
For example, one could write an emacs macro to show a string in
unescaped form - I did one in about 30 minutes (it would have
been faster if I were an elisp guru, which I certainly am not).
alignas to standardise alignment.
Here you don't even assert there is value, just list what the
feature does. In any case the question is moot, since C11
has settled on _Alignas (and _Static_assert), with 'alignas' and
'static_assert' as macros defined when certain standard headers
are included.
And for the bold, "auto" variable declarations.
Here you don't even make an assertion about it, just list it as
an example. Simply making the statement that a feature "would
improve and stand alone in C" is never going to be convincing.
The above appears to sum up the difference in attitude between
the C and C++ working groups. The latter are happy to incur the
cost (to them) of changes that have have benefits to their users
(us).
If I may speculate for a moment, I might list several reasons why
the C++ group is more willing to introduce new features than the C
group is. One, the C group places a higher weight on backwards
compatibility (and I believe this has been acknowledged by the C++
group) than the C++ group. Two, the C++ group puts a lower weight
on the cost to implementors (and implicitly other source processing
tools) than the C group does. Three, the C++ group puts a lower
weight on the cost to developers (of using a larger, more complicated
language) than the C group does. Four, the C++ group puts in less
effort, comparatively speaking, considering all the potential
ramifications of proposed features than the C group does. This last
point is understandable in light of the scope and complexity of the
kinds of language features the C++ group has to deal with; still,
it says something about the language and what it takes to get new
features into it.
Whatever one's views might be about what weighting functions are
appropriate, if one is proposing a change to the C language, it's
important to understand and address the weighting functions used
by the C community (of C developers generally, and the ISO C groups
in particular) in trying to get a proposed feature adopted. My
point all along has been about how to make a compelling argument
to increase the chance that will happen.