VLA question

M

Malcolm McLean

As to the "whole is greater than the sum of the parts" idea, I
believe if individual changes don't stand on their own merits,
then it's even worse to include them as a group. Let's take the
'const'-defined array bound as an example. This language feature
adds no significant expressive power to the language; it's
simply another way of doing something that can already be done
with about the same amount of code writing. There may be some
things about it that are better, and some things that are worse,
but certainly it isn't clearly better -- it's just different. So
now what happens if rather than one of those we add 25 of them?
Just yesterday I was writing an Ising model (about to go on sourceforge).
Nothing serious, just a framework for people to mess about with and
see the results graphically.
But you need a decent random number generator for Monte Carlo simulations.
Fortunately the inventor of the Mersenne twister has provided source
code. But in C99. It #includes stdint.h, and in makes heavy use of
inline functions, defined in the header. Microsoft's C++ compiler which
I have to use doesn't understand this. So I had to move all the inline
functions into the main body of the file, and typedef the stdint types.
Quite a bit of work, even for a small routine.
In programming, the trivial is important, because of they way that one
tiny glitch can break an entire build (or worse, an entire program).

It's better to add 25 small changes in a bundle than introduce them one
by one, however. Then the code is either C89 or C += 0.5, you don't have
25^2 patching possibilities, every one of which needs testing before
you can be absolutely sure it won't break.
 
J

James Kuyper

On 07/05/2013 01:54 AM, Ian Collins wrote:
....
There are number of C++11 additions that would improve and stand alone
in C in similar ways to C++, some examples: ....
alignas to standardise alignment.

How would C++'s alignas improve upon C's _Alignas()?
 
T

Tim Rentsch

Malcolm McLean said:
Just yesterday I was writing an Ising model (about to go on
sourceforge). Nothing serious, just a framework for people to
mess about with and see the results graphically.

But you need a decent random number generator for Monte Carlo
simulations. Fortunately the inventor of the Mersenne twister has
provided source code. But in C99. It #includes stdint.h, and in
makes heavy use of inline functions, defined in the header.
Microsoft's C++ compiler which I have to use doesn't understand
this. So I had to move all the inline functions into the main
body of the file, and typedef the stdint types.

The Microsoft compiler is non-conforming, with no indication that
will ever change. Hence it has no bearing on a discussion about
whether or what to change in ISO C.
Quite a bit of work, even for a small routine.

In programming, the trivial is important, because of they way that
one tiny glitch can break an entire build (or worse, an entire
program).

I hope you don't expect any sympathy after choosing to use a
compiler that was willfully made non-conforming, not out of
technical indifference but as part of Microsoft's malevolent
business strategy.
It's better to add 25 small changes in a bundle than introduce
them one by one, however. [snip elaboration]

Perhaps so but it's not relevant to the point under discussion.
 
T

Tim Rentsch

Ian Collins said:
Tim said:
My reaction is just the opposite. For starters, I think the gap
has gotten wider rather than narrower. Moreover it is likely to
continue growing in the future, beause of the different design
philosophies of the respective groups - the C group is generally
conservative, the C++ group more open to accommodating new
features.

It looks like this will continue to be the case, given the active
discussion of new features for the next C++ revision.

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

2. In advocating a particular feature or set of features, it's
common to support the new feature by saying, in effect, "this
feature has the following benefits'. Of course there are
benefits; every programming language feature anyone has ever
thought of has _some_ benefits. The operative question is
whether what's gained is worth the cost. Any argument that only
presents one side, and makes no effort to weigh one side against
the other, will never be a compelling argument for adding a new
feature to a standardized language, because there is inherently a
cost, and a non-trivial cost, in making the change, both
sheparding the change through the process, and the continuing
cost that comes from having a larger language definition.
 
I

Ian Collins

Malcolm said:
Just yesterday I was writing an Ising model (about to go on sourceforge).
Nothing serious, just a framework for people to mess about with and
see the results graphically.
But you need a decent random number generator for Monte Carlo simulations.
Fortunately the inventor of the Mersenne twister has provided source
code. But in C99. It #includes stdint.h, and in makes heavy use of
inline functions, defined in the header. Microsoft's C++ compiler which
I have to use doesn't understand this. So I had to move all the inline
functions into the main body of the file, and typedef the stdint types.
Quite a bit of work, even for a small routine.
In programming, the trivial is important, because of they way that one
tiny glitch can break an entire build (or worse, an entire program).

Last time I looked, stdint.h was included in C++11 which Microsoft is
aiming to support. Time up either upgrade, or migrate to a proper C
compiler.
 
I

Ian Collins

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. The examples I cited were added to C++ to make life
easier for the programmer in use cases equally applicable to a C
programmer. They are features I've embraced and miss when using older
tools.
2. In advocating a particular feature or set of features, it's
common to support the new feature by saying, in effect, "this
feature has the following benefits'. Of course there are
benefits; every programming language feature anyone has ever
thought of has _some_ benefits. The operative question is
whether what's gained is worth the cost. Any argument that only
presents one side, and makes no effort to weigh one side against
the other, will never be a compelling argument for adding a new
feature to a standardized language, because there is inherently a
cost, and a non-trivial cost, in making the change, both
sheparding the change through the process, and the continuing
cost that comes from having a larger language definition.

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

James Kuyper

Tim Rentsch wrote: ....

One could say the same thing to the proponent of round wheels in a
square world.

Now you've got me thinking of "The Three Cornered Wheel" by Poul Anderson.

Such a proponent could be criticized as having relied upon "proof by
assertion" only if he failed to describe any of the reasons why round
wheels are better. Why would he do that? The only reason I can think of
for not giving them is if he secretly wanted the proposal to fail.
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).

That's the wrong distinction. The "continuing cost that comes from
having a larger language definition" is paid primarily by the users, who
have to understand the larger language definition.
 
I

Ian Collins

James said:
Now you've got me thinking of "The Three Cornered Wheel" by Poul Anderson.

Such a proponent could be criticized as having relied upon "proof by
assertion" only if he failed to describe any of the reasons why round
wheels are better. Why would he do that? The only reason I can think of
for not giving them is if he secretly wanted the proposal to fail.

Which is why I did offer reasons.

Some amusing examples justifying raw string literals can be found on
Bjarne Stroustrup's page here:

http://www.stroustrup.com/C++11FAQ.html#raw-strings

I know which I'd rather have to type or maintain!
That's the wrong distinction. The "continuing cost that comes from
having a larger language definition" is paid primarily by the users, who
have to understand the larger language definition.

I don't agree with that. Yes C++11 is bigger than C++98, but the more
complex language absorbs some of the complexity from my code, so I gain
and so does the reader. I only have to learn the new stuff once but I
benefit from it every day.
 
Ö

Öö Tiib

That's the wrong distinction. The "continuing cost that comes from
having a larger language definition" is paid primarily by the users, who
have to understand the larger language definition.

Note that there may be different costs that the users of the languages
have to pay.

My impression is that C is used close to whole. Style guide for C project
is maximally a little wiki page. How to name, how to use white-space and
what *obscurities* *are* *banned*. It can be even omitted and just taught
from specialist to specialist with few peer reviews.

C++ has been always used as a (lot smaller) subset of the language.
Defining such subset is hard with C++98 because its features and its
standard library have strange caps in functionality. C++ style guide
is therefore often like a book about what language features are
allowed and when. The choice heavily depends on problem domain so for
a person switching teams (even in same little company) the differences
between C++98 and C++98 may feel rather major and it may take several
days to learn.

C++11 did seemingly fill several of caps and it seems to be actually
possible to reduce and simplify the guides with it (despite the
language did grow a lot). I have to admit that C++11 is too fresh to
be definite here, only few projects have been completed with it and
near future will show how it went but so far looks good.
 
M

Malcolm McLean

Malcolm McLean wrote:


Last time I looked, stdint.h was included in C++11 which Microsoft is
aiming to support. Time up either upgrade, or migrate to a proper C
compiler.
Purchase of a new personal machine is imminent, and I'm very tempted to
to go the Linux route. I know the Windows API quite well, but it seems
MS are taking it away. So now might be the time to make the break.

But I want users to be able to run my graphical programs. It used to be
easy - simply write for a PC. Now it seems to be a difficult thing to
compile and distribute a graphical C program which has a decent user base.
 
L

Lowell Gilbert

Ian Collins said:
There are number of C++11 additions that would improve and stand alone
in C in similar ways to C++, some examples:

Ah, specifics! Something to actually work with...
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.

In practice, the problems with doing these kinds of checks in C as it
stands mean that people don't. I often set up special unit test
frameworks to check assertions that in theory could be done at
compile-time, but despite being easier for other people to read, it has
other drawbacks. I'd definitely like to have this feature in C.
Initialisations preventing narrowing. Removes another source of
unexpected behaviour.

You can already have compilers warn you about these cases, and a lot of
people do, so the benefit is somewhat limited. By the same token, the
cost is fairly limited. Although I might be wrong on that; perhaps this
would break a lot of existing code in ways I don't foresee.
General compile time constants with constexpr. This would be
particularly useful in the embedded world were you want to minimise
RAM use.

I don't follow this point. Keeping your constants out of writable memory
isn't a real problem in C, although sometimes you have to go through a
few extraneous hoops to make sure it happens. The major generality this
feature brings to C++ is to make a particular piece of code
(stereotypically an initializer, although not limited to that) work
better with different types, and that doesn't really apply in C.
nullptr. Removes another source of unexpected behaviour.

Like constexpr, this makes little difference in the absence of
polymorphism. In C++, the automatic distinction between ((null *)0)
and ((int) 0) is a significant improvement, but in C, you call a
function, and the parameter is expected to be a particular type.
Raw string literals. Removes another potential source of unexpected
behaviour and hard to read code (how many slashes do I need?).

Only matters with regular expressions, but that's an important special
case. I don't really know how much effort this is for compiler writers.
alignas to standardise alignment.

I don't have an opinion here. I do work on deeply embedded code, and I
often need different alignment requirements than the compiler knows to
do, but almost always, the reasons I need those special alignments are
just as non-portable as the syntax that I use to force them, so it
wouldn't affect me. But I can see that might not apply to others.

Just don't spell it the same as C++...
And for the bold, "auto" variable declarations.

Syntactic sugar, even in C++. Sufficiently expressive in C++ to make the
code clearer, but I can't imagine a realistic situation in C where it
would help anywhere near as much as it does for C++ templates.
None of these are particularity radical, but they would make
programmer's life just that little bit easier.

They're all worthwhile additions to C++, but most of them are only
useful to a programmer if his code (or even just his brain) tries to
be compatible with C++.

Be well.
 
J

James Kuyper

Which is why I did offer reasons.

Then why didn't you simply say so? I don't see what point was served by
bringing up the round wheel proponent, not even as an analogy. If you'd
specified that the round wheel proponent had presented supporting
arguments, then the analogy would have had a point - but it would have
been even more relevant to point out that you had given supporting
arguments.
 
J

James Kuyper

On 07/06/2013 12:58 PM, Lowell Gilbert wrote:
....
Syntactic sugar, even in C++. ...

Equivalent C++ code that would do the same thing as auto is extremely
complicated. I know of no C features that would justify describing as
mere "syntactic sugar" a change of "auto" to have the meaning it has in
C++. Would you care to provide equivalent standard C code that would be
equivalent to the following code, if that change were made:

#include <time.h>
// ...
time_t t;
clock_t c;
// set the values of t and c
// ...
auto sum = c+t;

Keep in mind that time_t and clock_t can each be any real type; that
includes both _Bool and long double, and anything in between.
... Sufficiently expressive in C++ to make the
code clearer, but I can't imagine a realistic situation in C where it
would help anywhere near as much as it does for C++ templates.

C++ templates are certainly the biggest thing that makes C++ "auto"
useful. However, C++ "auto" can be useful in any context where it is
non-trivial to determine the type of an expression, and C provides some
mechanisms that allow that to be the case. Libraries that specify their
interfaces in terms of typedefs (such as clock_t or time_t), reserving
the right to change the definition of the typedef on different platforms
or in different versions of the library, are one such mechanism. A macro
that defines a variable whose type depends upon the context in which the
macro is expanded is another. The type that results from integer
promotions and the usual arithmetic conversions can, in principle, be
determined by using #if's based upon corresponding *_MAX values from
<limits.h>, but doing can be rather complicated, particularly if the
types of the operands are specified using typedefs, and using C++ "auto"
would be a lot simpler.
 
L

Lowell Gilbert

James Kuyper said:
On 07/06/2013 12:58 PM, Lowell Gilbert wrote:
...

Equivalent C++ code that would do the same thing as auto is extremely
complicated. I know of no C features that would justify describing as
mere "syntactic sugar" a change of "auto" to have the meaning it has in
C++. Would you care to provide equivalent standard C code that would be
equivalent to the following code, if that change were made:

#include <time.h>
// ...
time_t t;
clock_t c;
// set the values of t and c
// ...
auto sum = c+t;

Keep in mind that time_t and clock_t can each be any real type; that
includes both _Bool and long double, and anything in between.

Fair enough, although I don't really think of representation as part of
the type in C the way I do in C++.
 
J

James Kuyper

Fair enough, although I don't really think of representation as part of
the type in C the way I do in C++.

That response raises more questions than it answers.

What is different between C and C++ that makes you feel that way? C++
has more complicated user-defined types than C, but those more
complicated types are built on the same foundation as C's simpler types,
and the representation of types is a key part of that common foundation.

Why do you not think of the representation as part of a C type?
Representation is one of most fundamental characteristics of any C
object type; all of section 6.2.6 is devoted to describing what the C
standard does and does not mandate with respect to the representation.
What are the things that you do think of as being "part" of a C data
type other than it's representation? The main other parts I can think of
are type category membership, and the member list for struct, union and
enum types. I thought of including "the list of permitted operations on
things of that type", but that list is determined by the type category.
I thought of including sizeof(type), but that's just one aspect of the
representation.

Finally, and most importantly - what does that have to do with the point
I raised about your dismissal of the C++ 'auto' keyword as mere
syntactic sugar?
 
T

Tim Rentsch

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.
 

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,076
Messages
2,570,565
Members
47,200
Latest member
Vanessa98N

Latest Threads

Top