strange warning

K

Keith Thompson

BartC said:
He has a point. C's implementation of arrays is somewhat lightweight.

Then he could have made that point rather than claiming that "C does not
have arrays".

C arrays, unlike arrays in many other languages, are built on top of
lower-level constructs, and yes, those concepts often show through.
I don't claim that C's design is ideal, but C absolutely does have
arrays (though not as, in some sense, first-class types).
 
K

Keith Thompson

Dr Nick said:
It has, but I think the first part of this argument is somewhat
backwards. If we only had something that works like calloc it would be
a bit stronger, but since we do almost all dynamic memory with malloc
and realloc and they work in raw bytes, I think it's fairer to say that C
pointer arithmetic is so defined so that C doesn't really need arrays.

I"m not sure what you mean by "If we only had something that works like
calloc". We do have calloc.

Yes, C really does need arrays. Fortunately, it has them.
 
D

David Brown

A quibble: The C standard defines the term "compatible types",
and the definition is much more strict than that. The definition
is in N1570 6.2.7p1, with references to several other sections.
[snip]

n1570 which I looked up is the C11 standard. I do not know a thing about
that and my gcc doesn't seem to have any new possible C11 headers that I
see. I must conclude that gcc isn't C11 compliant. I am just staring to use
/some/ of C99.

Bill

n1570 is a popular document because it was the last draft standard of
C11 before the final standard was made. There is (as far as I know)
almost no difference between n1570 and the real C11 standard, except
that n1570 is freely (legally) available on the web, while you have to
pay for the real standard. Thus people use n1570 rather than buying the
C11 standard. I don't know if there is an equivalent for a good draft
of C99 that is available as easily, but I'm sure someone will let us
know if there is.

There is no difference in this sort of area between C11 and C99, so
n1570 is a fine reference here.

As for gcc's C11 support, look at: <http://gcc.gnu.org/wiki/C11Status>
for a summary. Also look at
<http://en.wikipedia.org/wiki/C11_(C_standard_revision)> for the
differences between C99 and C11. In my view, there is not a lot to get
excited about - static assertions are nice, and atomic variables /may/
be useful depending on how they are implemented.
 
B

Ben Bacarisse

David Brown said:
n1570 is a popular document because it was the last draft standard of
C11 before the final standard was made. There is (as far as I know)
almost no difference between n1570 and the real C11 standard, except
that n1570 is freely (legally) available on the web, while you have to
pay for the real standard. Thus people use n1570 rather than buying
the C11 standard. I don't know if there is an equivalent for a good
draft of C99 that is available as easily, but I'm sure someone will
let us know if there is.

n1256.pdf

<snip>
 
B

Ben Bacarisse

Ian Collins said:
You appear to live in the land of the abstract. For those of us who
live in the real world, fixed length arrays are a normal part of our
programming life.

"Yes", "they are". ;-)
 
K

Keith Thompson

David Brown said:
n1570 is a popular document because it was the last draft standard of
C11 before the final standard was made. There is (as far as I know)
almost no difference between n1570 and the real C11 standard, except
that n1570 is freely (legally) available on the web, while you have to
pay for the real standard. Thus people use n1570 rather than buying the
C11 standard. I don't know if there is an equivalent for a good draft
of C99 that is available as easily, but I'm sure someone will let us
know if there is.

N1256 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>
is a freely available draft that contains the official C99 standard
with the three Technical Corrigenda merged into it. It was published
after the release of the C99 standard, unlike N1570, which was
published before the release of the C11 standard. N1256 is, for
most purposes, actually more useful than the official C99 standard.
(The three Technical Corrigenda are available at no charge.)

Larry Jones, a commitee member, posted a summary of the differences
between N1570 and C11 last year in comp.std.c:

There are a number of them, but most are just minor editorial
tweaks, changes to boilerplate text, and shuffling things around
to keep the powers that be happy. The biggest change was removing
_Alignof from a bunch of places it shouldn't have been added
(based on the erroneous notion that it takes either a type or an
expression like sizeof does when it really only takes a type):
6.3.2.1p2, p3, p4, fn. 65; and 6.7.1 fn. 121.

N1570 failed to specify values for the __STDC_VERSION__ and
__STDC_LIB_EXT1__ macros. The released C11 standard did not correct
these errors. They were corrected in the first (and, so far, only)
Technical Corrigendum; both expand to 201112L.
There is no difference in this sort of area between C11 and C99, so
n1570 is a fine reference here.

As for gcc's C11 support, look at: <http://gcc.gnu.org/wiki/C11Status>
for a summary. Also look at
<http://en.wikipedia.org/wiki/C11_(C_standard_revision)> for the
differences between C99 and C11. In my view, there is not a lot to get
excited about - static assertions are nice, and atomic variables /may/
be useful depending on how they are implemented.

Standard support for threading could be useful, but so far I'm not aware
of any C11 implementations that don't already support POSIX threads.
 
M

Malcolm McLean

Malcolm McLean wrote:

You appear to live in the land of the abstract. For those of us who
live in the real world, fixed length arrays are a normal part of our
programming life.
When a function doesn't make any calls to IO routines, and scales in
N, then that releases something. All we need is a universal language for
specifying the input and output or such algorithms, and the manipulations
they perform, and we've created something permanent and as useful for
as long as the specification matches something in the real world.

That's real programming. I'm not saying you will never use a fixed-length
array. But they're not so common and usually a sign that you've coded
the algorithm incorrectly.
 
I

Ian Collins

Malcolm said:
When a function doesn't make any calls to IO routines, and scales in
N, then that releases something. All we need is a universal language for
specifying the input and output or such algorithms, and the manipulations
they perform, and we've created something permanent and as useful for
as long as the specification matches something in the real world.

That's real programming. I'm not saying you will never use a fixed-length
array. But they're not so common and usually a sign that you've coded
the algorithm incorrectly.

Algorithms often have to work with physical or other externally defined
fixed sized entities. Probably >50% of the code I write is dealing with
these fixed sized things. Am I coding incorrectly?
 
D

David Brown

Algorithms often have to work with physical or other externally defined
fixed sized entities. Probably >50% of the code I write is dealing with
these fixed sized things. Am I coding incorrectly?

For my own part, over 80% of the code I write deals with fixed sizes
(and most of the code I write that doesn't have fixed sizes is written
in Python rather than C).

For smaller embedded systems, fixed sizes are definitely the norm -
malloc and other dynamic allocations (such as VLA) are shunned, or
banned outright by many coding standards.

Of course, such small embedded systems are only one area of C
programming. But as higher level languages take more of a share of "big
system" programming and there is more and more embedded programming
being done, a larger proportion of C programming is embedded.
 
M

Malcolm McLean

Algorithms often have to work with physical or other externally defined
fixed sized entities. Probably >50% of the code I write is dealing with
these fixed sized things. Am I coding incorrectly?
It's a sign that you're not using very rigourous methods, but only a
sign. There's often a conflict between micro-efficiency and good design,
and you don't always want to resolve it in favour of good design.

Then if the algorithms are essentially trivial then it matters a lot less
about porting them. I've just spent about two months on a single function,
for example. Obviously we don't want to spend another two months taking
out all the non-general assumptions if the company decide to target a
new platform. If the algorithm is just "step through the array and get
the closest value to x" then that takes only a few minutes to write,
it's much less important to make sure you pass in N as a parameter.
Would saving couple of bytes of stack space actually make the fixed
method better? Well, sometimes. It just depends on the situation.
 
I

Ian Collins

David said:
For my own part, over 80% of the code I write deals with fixed sizes
(and most of the code I write that doesn't have fixed sizes is written
in Python rather than C).

For smaller embedded systems, fixed sizes are definitely the norm -
malloc and other dynamic allocations (such as VLA) are shunned, or
banned outright by many coding standards.

Of course, such small embedded systems are only one area of C
programming. But as higher level languages take more of a share of "big
system" programming and there is more and more embedded programming
being done, a larger proportion of C programming is embedded.

I was going to replay saying that Malcolm tends to trivialise the kind
of work we do, but I see He has already done so in his reply to my post.
 
I

Ian Collins

Malcolm said:
It's a sign that you're not using very rigourous methods, but only a
sign. There's often a conflict between micro-efficiency and good design,
and you don't always want to resolve it in favour of good design.

Hello, real world calling...

So when using the fixed sizes defined by my system's headers for the
kernel data structures I am processing I'm micro-optimising? Give me a
break.
 
N

Noob

Osmium said:
When C sees
int a[10];
it goes into a little dance. It sets aside room for 10 ints in one place
and in another place it creates a variable named 'a'. They set a to point
at the first int in the space set aside. Bill's problem originates with the
variable named 'a'. Thus my answer to him.

You might be thinking of this kind of definition:

char *s1 = "abcdefg";

Contrast with

char s2[] = "abcdefg";

Regards.
 
M

Malcolm McLean

Malcolm McLean wrote:

So when using the fixed sizes defined by my system's headers for the
kernel data structures I am processing I'm micro-optimising? Give me a
break.
The person who wrote the kernel headers has decided to define the interface
as raw structures and a fixed size, abstracted a bit by a hash define.

A clear case of micro-optimisation. But not necessarily a bad decision, given the
limitations of current systems, or maybe the fact that the kernel is a legacy
system that has been continuously developed back from the days when 640k
was enough for anybody.
You then use N directly instead of reading it at one place then passing it to
every subroutine. Another clear case of micro-optimisation. Maybe defensible,
"micro-optimisation" has a technical meaning, it doesn't mean "optimisation
that gains only a bit a run time".
There's also the issue of keeping interfaces clean. That's a issue with C, largely
solved by the use of structures, but not entirely. The basic strategy is to
populate a structure with pointers to the kernel data structures and their sizes,
the pass it to the subroutines to take out the dependencies on the fixed structures.
So we can then reuse the code if the kernel interface changes other than by
adding or subtracting an entry from a structure array. But again, that's not
necessarily worth doing, largely for micro efficiency reasons, but also because
you're maybe making the interfaces harder to document and use. You have to
look at every situation, there are general principles, but it's not as simple as
blindly applying a rule.
 
I

Ian Collins

Malcolm said:
The person who wrote the kernel headers has decided to define the interface
as raw structures and a fixed size, abstracted a bit by a hash define.

Or an enum.
A clear case of micro-optimisation.

No it isn't. It's a sign of an environment where dynamic allocation is
frowned upon or even banned.

Regardless of the motivation, my original point that fixed arrays are
widely used in real world code still holds.
 
M

Malcolm McLean

You have to look at every situation, there are general principles, but it's
not as simple as blindly applying a rule.
Lets explain further.

We've got this situation

typedef struct
{
int a;
int b;
} KERNELSTRUCTURE;

#define NKERNELSTRUCTS 10

KERNELSTRUCTURE kernelstructs[10]; /* writing to these structures has side effects ! */

So how do we handle it?

typedef struct
{
int N;
KERNELSTRUCTURE *kernel; /*the bits that manipulate the kernel */
KERNELSTRUCTURE *copy; /* what we'll be reading and writing from */
bool *dirty; /* possibly keep track of dirty structures */
} ABSTRACTION;


Then we set one up by reading the kernel at program start.
Then we pass an ABSTRACTION * to all out subroutines. So what we've done is we've converted
the subroutines from IO routines, which have side-effects, to pure bit-shuffling functions. All
they're doing is shuffling bits about in copy.
The we have one function.

void synch(ABSTACTION *abs)
{
/* go through updating dirty kernel entries */
/* maybe you also need to read the kernel again */
}

That's the one place we update the kernel, it's the only function which can have any side
effects.

What's the advantage? Well now we've decoupled testing and debugging from the
particular kernel. We run our subroutines on a UNIX box and verify that for every kernel
state we're interested in, they put copy into the correct state. All the bit shuffling is
correct.
It simply remains to hook up sync to a real kernel on real hardware.

Now of course you can have all sorts of problems, such as needing to update the
kernel and get back a result from the system immediately. There might not be
time to go all the way back up the call tree, call synch, then go back down again to
process the answer. This design is not a magic bullet which can be blindly applied.

But it's the sort of thing I'm talking about.

And you think I don't "live in the real world?".
 
K

Kenny McCormack

Malcolm McLean said:
And you think I don't "live in the real world?".

Seeing a CLC reg telling *anyone* *anything* about "the real world" is a
screamer in and of itself.

(Something about glass houses...)
 
M

Malcolm McLean

Seeing a CLC reg telling *anyone* *anything* about "the real world" is a
screamer in and of itself.

(Something about glass houses...)
Ian does live in the real world. But he's a bit like a car mechanic who's been on
lots of courses, and has twenty years' experience, and knows exactly what type
of brake pad you need to fit on the Ford Fiesta and why the fuel lines on the
Mini Cooper can be a bit dodgy. So he thinks he knows everything there is to
know about cars.
 
I

Ian Collins

Malcolm said:
Ian does live in the real world. But he's a bit like a car mechanic who's been on
lots of courses, and has twenty years' experience, and knows exactly what type
of brake pad you need to fit on the Ford Fiesta and why the fuel lines on the
Mini Cooper can be a bit dodgy. So he thinks he knows everything there is to
know about cars.

Bullshit. But do know what, and how useful, a fixed length array is.
 
J

James Kuyper

I"m not sure what you mean by "If we only had something that works like
calloc". We do have calloc.

I think he means "if calloc() were the only available way to dynamically
allocate memory". Possibly, he might also be talking about a
hypothetical language in which arrays could not be declared, so that
dynamically allocating memory was the only way to create a pointer to
two or more consecutive objects of a single type.
 

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