Maker Pro
Maker Pro

Re: Intel details future Larrabee graphics chip

W

Wilco Dijkstra

Jan 1, 1970
0
Nick Maclaren said:
|>
|> > |> It's certainly true the C standard is one of the worst specified. However most
|> > |> compiler writers agree about the major omissions and platforms have ABIs that
|> > |> specify everything else needed for binary compatibility (that includes features
|> > |> like volatile, bitfield details etc). So things are not as bad in reality.
|> >
|> > Er, no. I have a LOT of experience with serious code porting, and
|> > am used as an expert of last resort. Most niches have their own
|> > interpretations of C, but none of them use the same ones, and only
|> > programmers with a very wide experience can write portable code.
|>
|> Can you give examples of such different interpretations? There are a
|> few areas that people disagree about, but it often doesn't matter much.

It does as soon as you switch on serious optimisation, or use a CPU
with unusual characteristics; both are common in HPC and rare outside
it. Note that compilers like gcc do not have any options that count
as serious optimisation.

Which particular loop optimizations do you mean? I worked on a compiler
which did advanced HPC loop optimizations. I did find a lot of bugs in the
optimizations but none had anything to do with the interpretation of the C
standard. Do you have an example?
I could send you my Objects diatribe, unless you already have it,
which describes one aspect. You can also add anything involving
sequence points (including functions in the library that may be
implemented as macros), anything involving alignment, when a library
function must return an error (if ever) and when it is allowed to
flag no error and go bananas. And more.

You have to give more specific examples of differences of interpretation.
I'd like to hear about failures of real software as a direct result of these
differences. I haven't seen any in over 12 years of compiler design besides
obviously broken compilers.
|> Interestingly most code is widely portable despite most programmers
|> having little understanding about portability and violating the C standard in
|> almost every respect.

That is completely wrong, as you will discover if you ever need to
port to a system that isn't just a variant of one you are familiar
with. Perhaps 1% of even the better 'public domain' sources will
compile and run on such systems - I got a lot of messages from
people flabberghasted that my C did.

I bet that most code will compile and run without too much trouble.
C doesn't allow that much variation in targets. And the variation it
does allow (eg. one-complement) is not something sane CPU
designers would consider nowadays.
|> Actually you don't need any "autoconfiguring" in C. Much of that was
|> needed due to badly broken non-conformant Unix compilers. I do see
|> such terrible mess every now and again, with people declaring builtin
|> functions incorrectly as otherwise "it wouldn't compile on compiler X"...

Many of those are actually defects in the standard, if you look more
closely.

I did look closely at some of the issues at the time, but they had nothing
to do with the standard, it was just working around broken compilers.
There is also a lot of software around that blatantly assumes there is
|> Properly sized types like int32_t have finally been standardized, so the
|> only configuration you need is the selection between the various extensions
|> that have not yet been standardized (although things like __declspec are
|> widely accepted nowadays).

"Properly sized types like int32_t", forsooth! Those abominations
are precisely the wrong way to achieve portability over a wide range
of systems or over the long term. I shall be dead and buried when
the 64->128 change hits, but people will discover their error then,
oh, yes, they will!

Not specifying the exact size of types is one of C's worst mistakes.
Using sized types is the right way to achieve portability over a wide
range of existing and future systems (including ones that have different
register sizes). The change to 128-bit is not going to affect this software
precisely because it already uses correctly sized types.
|> > A simple question: have you ever ported a significant amount of
|> > code (say, > 250,000 lines in > 10 independent programs written
|> > by people you have no contact with) to a system with a conforming
|> > C system, based on different concepts to anything the authors
|> > were familiar with? I have.
|>
|> I've done a lot of porting and know most of the problems. It's not nearly
|> as bad as you claim. Many "porting" issues are actually caused by bugs
|> and limitations in the underlying OS. I suggest that your experience is
|> partly colored by the fact that people ask you as a last resort.

Partly, yes. But I am pretty certain that my experience is a lot
wider than yours. I really do mean different CONCEPTS - start with
IBM MVS and move on to a Hitachi SR2201, just during the C era.

It's true that supercomputers of the past had wacky integer sizes and formats
or only supported 64-bit int/double and nothing else. But these systems
weren't designed to run off-the-shelf C, they were built to run FP code fast
(ie. Fortran, not C). In any case I'm pretty certain my experience applies to a
much larger market than yours :)

Wilco
 
C

Chris M. Thomasson

Jan 1, 1970
0
John Larkin said:
Digital logic designers tend to think in terms of concurrent,
synchronous state machines that operate on data. Programmers tend to
think in terms of sequential processes that have zillions of states, a
minute fraction of which they ever really consider. Ignoring data for
a moment, think of a sequential program state as being its program
counter, and the state transitions being the drunkard's walk through
all the possible paths between branches. Now add the data back in. Now
connect it to a bunch of other "state machines" coded by other
programmers, with badly documented or undocumented interfaces, and
next allow a lot of asynchronous events.

I read that for a major bunch of Windows APIs, the only documantation
was the source code itself.




C is a bad language that has spawned a worse culture.
[...]

IMHO, C is only as bad as the programmer who uses it... BTW, what you think
of C++? The Air Force seems to like it a lot for systems programming:

http://www.research.att.com/~bs/JSF-AV-rules.pdf

I also believe that systems software in the Mars Lander was created in C.
 
W

Wilco Dijkstra

Jan 1, 1970
0
Martin Brown said:
Not quite. I doubt if a poor programmer could ever get a program to compile with an Ada compiler. Pascal or Modula2
would protect the world from a lot of the pointer casting disasters that C encourages.

I agree C is a bit easier to learn syntactically and so attracts a larger share
of bad programmers. But in terms of types there isn't a huge difference -
you can't assign incompatible pointers in C without a cast. One issue is that
compilers don't give a warning when casts are likely incorrect (such as
casting to a type with higher alignment).
Even experienced programmers can make bad errors with pointers. You could make a fairly strong case for only having
arrays.

I doubt it. I've worked for many years on huge applications which use complex
data structures with lots of pointers. I've seen very few pointer related failures
despite using specialized memory allocators and all kinds of complex pointer
casting, unions etc. Most memory failures are null pointer accesses due to
simple mistakes.

There is certainly a good case for making pointers and arrays more distinct
in C to clear up the confusion between them and allow for bounds checking.
Pointers are the programming equivalent of having a rats nest of bare wires randomly soldered to points on your
circuit board with the other end hanging in the air waiting to touch something vital.

I guess you don't like pointers then :)

Wilco
 
W

Wilco Dijkstra

Jan 1, 1970
0
Chris M. Thomasson said:
C is a bad language that has spawned a worse culture.
[...]

IMHO, C is only as bad as the programmer who uses it... BTW, what you think of C++? The Air Force seems to like it a
lot for systems programming:

Exactly. You can write bad software in any language. Most Perl I've seen
is far worse than average C.

C++ is a lot better than C if you stick to a reasonable subset. The more
contentious parts are templates (mainly STL), exceptions and multiple
inheritance.
http://www.research.att.com/~bs/JSF-AV-rules.pdf

I also believe that systems software in the Mars Lander was created in C.

C/C++ are widely used in the embedded world including in safety critical
systems. Object oriented C++ is even used in most harddrives (they went
from 100% assembler to 99% C++ without losing performance) and other
realtime systems.

Some 13 years ago I wrote software for the Apache helicopter, all in C.
What shocked me was not at all the language used but the lack of quality of
the hundreds of pages of specifications and the programming capabilities
of some collegues. Getting it all working wasn't easy due to the complex and
time consuming ISO process used. One of the funny moments was when I
spotted 5 mistakes in a 20-line function that calculated the log2 of an integer
during a code review. I hope that wasn't their average bugrate!

Wilco
 
J

Joerg

Jan 1, 1970
0
John said:
Hardware design keeps moving up in abstraction level too. I used to
design opamps and voltage regulators out of transistors. Now I'm
dropping sixteen isolated delta-sigma ADCs around an FPGA that talks
to a 32-bit processor. That's sort of equivalent to building a
software system using all sorts of other people's subroutines. We did
just such a board recently, 16 channels of analog acquisition, from
thermocouples to +-250 volt input ranges, all the standard
thermocouple lookup tables, RTD reference junctions, built-in
self-test, VME interface. No breadboards, no prototype. The board has
1100 parts and the first one worked.

My designs seems to go the other way. Yeah, also lots of delta-sigmas
but even more transistor level designs. Main reason is that they often
can't find anyone else to do it so it all lands on my pile.

Hardware design works better than software. One reason is that the
component interfaces are better defined. Another reason is that we
check our work - each other's work - very carefully before we ever try
to build it, much less run it. Most engineering - civil, electrical,
mechanical, aerospace - works that way. People don't hack jet engine
cores and throw them on a test stand to see what blows up.

But people do hack AGW "science" :) SCNR.
 
J

Joerg

Jan 1, 1970
0
John said:
We still use discrete parts here and there, especially for the fast
stuff, and high-power things. A board is typically a mix of
high-abstraction parts - big complex chips - and a bunch of simpler
stuff. "Glue logic", which actually does logic, is rare nowadays.

Lots of opamps and precision resistors. One good resistor can cost
more than an opamp.

Our stuff isn't a cost-sensitive as some of yours, so we don't mind
using an opamp if it works a little better than a transistor. And our
placement cost is high, so we like to minimize parts count.

That's what I ran into a lot, whenever something is made domestically in
a western country placement costs are through the roof. When I design
circuits that will be produced on lines in Asia I can adopt a whole
different design philosophy where replacing a $1 chip with 15 discrete
jelly-bean parts makes a lot of sense.

People keep talking about analog programmable logic...

With me it's the other way around. I am not allowed to talk about it ;-)
 
N

Nick Maclaren

Jan 1, 1970
0
|>
|> > It does as soon as you switch on serious optimisation, or use a CPU
|> > with unusual characteristics; both are common in HPC and rare outside
|> > it. Note that compilers like gcc do not have any options that count
|> > as serious optimisation.
|>
|> Which particular loop optimizations do you mean? I worked on a compiler
|> which did advanced HPC loop optimizations. I did find a lot of bugs in the
|> optimizations but none had anything to do with the interpretation of the C
|> standard. Do you have an example?

I didn't say loop optimisations. But you could include any of the
aliasing ambiguities (type-dependent and other), the sequence point
ambiguities and so on. They are fairly well-known.

|> You have to give more specific examples of differences of interpretation.

As I said, I will send you my document if you like, which includes
examples and explanations. Otherwise I suggest that you look at the
archives of comp.std.c, which has dozens of examples. I don't have
time to search my records for other examples for you.

|> I'd like to hear about failures of real software as a direct result of these
|> differences. I haven't seen any in over 12 years of compiler design besides
|> obviously broken compilers.

And I have seen hundreds. But I do know the C standards pretty well,
and a lot of "obviously broken compilers" actually aren't.

|> I bet that most code will compile and run without too much trouble.
|> C doesn't allow that much variation in targets. And the variation it
|> does allow (eg. one-complement) is not something sane CPU
|> designers would consider nowadays.

The mind boggles. Have you READ the C standard?

|> Not specifying the exact size of types is one of C's worst mistakes.
|> Using sized types is the right way to achieve portability over a wide
|> range of existing and future systems (including ones that have different
|> register sizes). The change to 128-bit is not going to affect this software
|> precisely because it already uses correctly sized types.

On the contrary. Look, how many word size changes have you been
through? Some of my code has been through about a dozen, in
succession, often with NO changes. Code that screws 32 bits in
will not be able to handle data that exceeds that.

You are making PRECISELY the mistake that was made by the people
who coded the exact sizes of the IBM System/360 into their programs.
They learnt better, but have been replaced by a new set of kiddies,
determined to make the same old mistake :-(


Regards,
Nick Maclaren.
 
W

Wilco Dijkstra

Jan 1, 1970
0
Nick Maclaren said:
As I said, I will send you my document if you like, which includes
examples and explanations. Otherwise I suggest that you look at the
archives of comp.std.c, which has dozens of examples. I don't have
time to search my records for other examples for you.

I'd certainly be interested in the document. My email is above, just make
the obvious edit.
|> I bet that most code will compile and run without too much trouble.
|> C doesn't allow that much variation in targets. And the variation it
|> does allow (eg. one-complement) is not something sane CPU
|> designers would consider nowadays.

The mind boggles. Have you READ the C standard?

More than that. I've implemented it. Have you?

It's only when you implement the standard you realise many of the issues are
irrelevant in practice. Take sequence points for example. They are not even
modelled by most compilers, so whatever ambiguities there are, they simply
cannot become an issue. Similarly various standard pendantics are moaning
about shifts not being portable, but they can never mention a compiler that fails
to implement them as expected...

Btw Do you happen to know the reasoning behind signed left shifts being
undefined while right shifts are implementation defined?
|> Not specifying the exact size of types is one of C's worst mistakes.
|> Using sized types is the right way to achieve portability over a wide
|> range of existing and future systems (including ones that have different
|> register sizes). The change to 128-bit is not going to affect this software
|> precisely because it already uses correctly sized types.

On the contrary. Look, how many word size changes have you been
through? Some of my code has been through about a dozen, in
succession, often with NO changes. Code that screws 32 bits in
will not be able to handle data that exceeds that.

It will work as long as the compiler supports a 32-bit type - which it will of
course. But in the infinitesimal chance it doesn't, why couldn't one
emulate a 32-bit type, just like 32-bit systems emulate 64-bit types?
You are making PRECISELY the mistake that was made by the people
who coded the exact sizes of the IBM System/360 into their programs.
They learnt better, but have been replaced by a new set of kiddies,
determined to make the same old mistake :-(

Actually various other languages support sized types and most software
used them long before C99. In many cases it is essential for correctness
(imagine writing 32 bits to a peripheral when it expects 16 bits etc). So
you really have to come up with some extraordinary evidence to explain
why you think sized types are fundamentally wrong.

Wilco
 
J

JosephKK

Jan 1, 1970
0
I/O and user interface, just like now: device drivers and GUI's. Just
run them on separate CPUs, and have hardware control over anything
that could crash the system, specifically global memory mapping. There
have been OS's that, for example, pre-qualified the rights of DMA
controllers so even a rogue driver couldn't punch holes in memory at
random.

But hot swap? What do you mean? All the CPUs are on one chip.

John

There are several things in play here. More and more instruments have
ports for memory cards, usb memory sticks, usb printer ports, IOW
conventional UPNP style hot plug.

Then we are ever more using dynamic unit / core switch out if it makes
a detected error, even at the sub chip level now.
 
K

Kim Enkovaara

Jan 1, 1970
0
Martin said:
It might be an interesting academic study to see how the error rates of
hardware engineers using VHDL compare with those using Verilog tools for
the same sorts of design. The latter I believe is less strongly typed.

In real industry design flows things get more complicated, because
almost all of the Verilog flows seem to suggest the use of Lint
type of tools (actually they do much more than just rudimentary language
checks). Those tools do some of the checks that VHDL type system
does during the compilation as a part of the language.

--Kim
 
K

Kim Enkovaara

Jan 1, 1970
0
Bernd said:
Well, first of all, Verilog has way less types. There are only bits, bit
vectors, 32 bit integers, and floats. You can't use the latter for
synthesis; usually only bits and bit vectors are used for register data
types.

And all that changes even with the synthesizable subset of
SystemVerilog, it adds enums, structs etc. And synthesis tools are
starting to support those features already, because they are quite easy
to map to VHDL features, that the tools had to support in the past
already.
My experience is that people make way less errors in Verilog, because it's
all straight-forward, and not many traps to fall in. E.g. a typical VHDL
error is that you define an integer subrange from 0..F, instead of a 4 bit
vector, and then forget to mask the add, so that it doesn't wrap around but
fails instead.

I have also seen major errors in Verilog, because it's so easy to
connect two different width vectors together etc. All languages have
their pros and cons.

And the synthesis result for the integer and bitvector are the same. The
difference is that the other one traps in the simulation and the
designer has to think about the error. In HW there is no bounds
checking.

We also have to differentiate what is meant with an error. Is is
something that traps the simulation and it might be a bug, or is it
something that exists in the chip. I like code that traps as early as
possible and near the real problem, for that reason assertions and
bound checking are a real timesaver in verification.
My opinion towards good tools:

* Straight forward operations
* Simple semantics

At least Verilog blocking vs. nonblocking and general scheduling
semantics are not very simple. VHDL scheduling is much harder to
misuse.
* Don't offer several choices where one is sufficient

Sometimes people like to code differently, choices help that. In
SystemVerilog there are at least so many ways to do things that
most people should be happy :)
* Restrict people to a certain common style where the tool allows choices

Coding style definition is a good way to start endless religious wars :)

--Kim
 
B

Bernd Paysan

Jan 1, 1970
0
Kim said:
And the synthesis result for the integer and bitvector are the same. The
difference is that the other one traps in the simulation and the
designer has to think about the error. In HW there is no bounds
checking.

That's a big no-no. Synthesis is just another implementation of simulation,
so the semantics must be the same. If there is no proof that the trap can't
happen, I would say you aren't allowed to synthesize the construct.
We also have to differentiate what is meant with an error. Is is
something that traps the simulation and it might be a bug, or is it
something that exists in the chip. I like code that traps as early as
possible and near the real problem, for that reason assertions and
bound checking are a real timesaver in verification.

Yes, but assertions are an obvious verification tool, and not mixed with the
actual operation semantics. If I write in Verilog

if(addr > 10) begin
$display("Address out of bound: %d", addr);
$stop;
end

then this is perfectly synthesizable code, and I know that a failure in
simulation is actually a bug in some producer of the address.
At least Verilog blocking vs. nonblocking and general scheduling
semantics are not very simple. VHDL scheduling is much harder to
misuse.

Fortunately, the synthesis tools are usually very strict on the rules of
blocking vs. non-blocking, so if you misuse them, you get error messages.
Sometimes people like to code differently, choices help that. In
SystemVerilog there are at least so many ways to do things that
most people should be happy :)

SystemVerilog is a lot of VHDL with Verilog syntax (as you described above).
Coding style definition is a good way to start endless religious wars :)

If you design as a team, you don't have time for many different coding
styles. But certainly, you are right that people are religious about their
coding style - in the current chip we just examine, we found a bug which
came from a particularly risky way of coding something, and we already had
a discussion between two people when this was coded - the implementer
ignored the common practice, and the code he wrote was actually wrong.
 
N

Nick Maclaren

Jan 1, 1970
0
|>
|> > No, int32_t and friends became NECESSARY when the 32 to 64 wave hit,
|> > a simple example, and audio wave header spec:
|> > #ifndef _WAVE_HEADER_H_
|> > #define _WAVE_HEADER_H_
|> >
|> > typedef struct
|> > { /* header for WAV-Files */
|> > uint8_t main_chunk[4]; /* 'RIFF' */
|> > uint32_t length; /* length of file */
|>
|> This is precisely the wrong specification for a portable specification!
|>
|> Which byte order should be used for the length field?

Yes. Plus the fact that many interfaces use fields that have subtly
different value ranges or semantics than the ones specified by C.
But that wasn't my primary point.

The reason that the fixed-length fanatics are so wrong is that they
take a decision that is appropriate for external interfaces and
extend it to internal ones, and even the majority of workspace
variables. Let's take that mistake as an example.

The length is passed around as uint32_t, but so are rather a lot of
other fields. In a year or so, the program is upgraded to support
another interface, which allows 48- or 64-bit file lengths. Not
merely does the program now have to be hacked, sometimes extensively,
there is a high chance of missing some changes or changing something
that shouldn't have been. Then the program starts to corrupt data,
but typically only when handling very large files!

That is PRECISELY what has happened, not just in the IBM MVT/MVS
days, but more than once in the Unix era, yet nobody seems to learn.
10 years ago, most Unix utilities were solid with such bugs, for
exactly that reason - even when running in 64-bit mode, they often
started corrupting data or crashing after 2/4 GB.

Yet writing word size independent code is no harder than writing that
sort of mess - though you do need to regard most of C99 as anathema.
Such code typically doesn't even check whether 'words' are 32-bit or
64-bit, and would usually work with 36-, 48-, 60- or 128-bit ones.

|> The alternative is to hide the memory ordering behind access functions
|> that take care of any byte swapping that might be needed.

That is the only approach for genuine portability, of course, such
as when some new interface demands that you do bit-swapping, add
padding, or do other such unexpected munging.

Plus, of course, it is the way that any competent software engineer
does it, because it provides a place to put tracing hooks and hacks
for broken interface usages, as well as making it almost trivial to
add support for new interfaces.


Regards,
Nick Maclaren.
 
K

Kim Enkovaara

Jan 1, 1970
0
Bernd said:
That's a big no-no. Synthesis is just another implementation of simulation,
so the semantics must be the same. If there is no proof that the trap can't
happen, I would say you aren't allowed to synthesize the construct.

The synthesis works the same way as VHDL if range checking is disabled
in the simulator via command line. Range checking is just an extra
precaution, just like assertions which are not synthesizable in any
general tools, just in some very specialized tools.

Synthesis vs. simulation semantics are different, many structures
that happily simulate might not be really synthesizable, for example
many wait statements.

If the user is clueless, any language can't save from the disaster.
Yes, but assertions are an obvious verification tool, and not mixed with the
actual operation semantics. If I write in Verilog

if(addr > 10) begin
$display("Address out of bound: %d", addr);
$stop;
end

then this is perfectly synthesizable code, and I know that a failure in
simulation is actually a bug in some producer of the address.

But while synthesizing for real target the tool first says that $display
and $stop are not supported constructs, and after that it removes the
empty if, so nothing was actually generated. What is the difference to
VHDL and defining the address to be integer range 0..10?

With assertions I was more pointing to direction of PSL/SV assertions,
not the traditional ASSERT in VHDL or code based assertions.

Fortunately, the synthesis tools are usually very strict on the rules of
blocking vs. non-blocking, so if you misuse them, you get error messages.

And simulators can simulate same verilog code in many different ways.
Many commercial IP models behave differently depending on optimization
flags and simulators or simulator versions even. It seems that
especially in behavioral models verilog is usually very badly
misused. I hate debugging problems where first you have to figure
out with the standard at hand if the simulator or code is wrong, and
after that try to convince the original coder that he is wrong in his
assumptions about the language semantics.


--Kim
 
J

Jan Panteltje

Jan 1, 1970
0
No, int32_t and friends became NECESSARY when the 32 to 64 wave hit,
a simple example, and audio wave header spec:
#ifndef _WAVE_HEADER_H_
#define _WAVE_HEADER_H_

typedef struct
{ /* header for WAV-Files */
uint8_t main_chunk[4]; /* 'RIFF' */
uint32_t length; /* length of file */

This is precisely the wrong specification for a portable specification!

Which byte order should be used for the length field?

If we had something like uint32l_t/uint32b_t with explicit
little-/big-endian byte ordering, then it would be portable.

The only way to make the struct above portable would be to make all
16/32-bit variables arrays of 8-bit bytes instead, and then explicitly
specify how they are to be merged.

Using a shortcut specification as above would only be allowable as a
platform-specific optimization, guarded by #ifdef's, for
machine/compiler combinations which match the actual specification.

The alternative is to hide the memory ordering behind access functions
that take care of any byte swapping that might be needed.

Terje

That is all true, but one thing 'uint32_t length' makes clear here
is that the wave file can be at most 4GB long.
When moved to a larger size 'int' this is not obvious.
When going from 32 to 64 bit one could easily assume otherwise.

There is also an alignment problem with structures like this,
one could be tempted to just read a file header into the structure address,
however if the compiler aligns at 4 byte intervals, then you uint8_t may not
be where you expect it.
So there is always more to it, if you dig deeper.
 
J

Jan Panteltje

Jan 1, 1970
0
The length is passed around as uint32_t, but so are rather a lot of
other fields. In a year or so, the program is upgraded to support
another interface, which allows 48- or 64-bit file lengths.

That is babble.
A new file specification will have an other header, or will be in
an extention field of the current header.
The whole program would be a different one, as all length calculations
and checks would change.
I have been there, done that.

Using clearly specified variable width is GOOD, unless you want to go
back to BASIC.
:)
 
W

Wilco Dijkstra

Jan 1, 1970
0
Terje Mathisen said:
Indeed.

How many ways can you define such a function?

The only serious alternatives would be in the handling of negative-or-zero inputs or when rounding the actual fp
result to integer:

Do you want the Floor(), i.e. truncate, Ceil() or Round_to_nearest_or_even()?

Using the latest alternative could make it harder to come up with a perfect implementation, but otherwise it should be
trivial.

It was a trivial routine, just floor(log2(x)), so just finding the top bit that is set.
The mistakes were things like not handling zero, using signed rather than
unsigned variables, looping forever for some inputs, returning the floor result + 1.

Rather than just shifting the value right until it becomes zero, it created a mask
and shifted it left until it was *larger* than the input (which is not going to work
if you use a signed variable for it or if the input has bit 31 set etc).

My version was something like:

int log2_floor(unsigned x)
{
int n = -1;
for ( ; x != 0; x >>= 1)
n++;
return n;
}

Wilco
 
N

Nick Maclaren

Jan 1, 1970
0
|> >
|> >The length is passed around as uint32_t, but so are rather a lot of
|> >other fields. In a year or so, the program is upgraded to support
|> >another interface, which allows 48- or 64-bit file lengths.
|>
|> That is babble.
|> A new file specification will have an other header, or will be in
|> an extention field of the current header.
|> The whole program would be a different one, as all length calculations
|> and checks would change.
|> I have been there, done that.

Precisely. And, if you would learn from the experience of the past,
all you would have to change is the interface code - the rest of the
program would not even need inspecting.

Been there - done that. Many times, in many contexts.


Regards,
Nick Maclaren.
 
W

Wilco Dijkstra

Jan 1, 1970
0
Nick Maclaren said:
As I said, I will send you my document if you like, which includes
examples and explanations. Otherwise I suggest that you look at the
archives of comp.std.c, which has dozens of examples. I don't have
time to search my records for other examples for you.

I'd certainly be interested in the document. My email is above, just make
the obvious edit.
|> I bet that most code will compile and run without too much trouble.
|> C doesn't allow that much variation in targets. And the variation it
|> does allow (eg. one-complement) is not something sane CPU
|> designers would consider nowadays.

The mind boggles. Have you READ the C standard?

More than that. I've implemented it. Have you?

It's only when you implement the standard you realise many of the issues are
irrelevant in practice. Take sequence points for example. They are not even
modelled by most compilers, so whatever ambiguities there are, they simply
cannot become an issue. Similarly various standard pendantics are moaning
about shifts not being portable, but they can never mention a compiler that fails
to implement them as expected...

Btw Do you happen to know the reasoning behind signed left shifts being
undefined while right shifts are implementation defined?
|> Not specifying the exact size of types is one of C's worst mistakes.
|> Using sized types is the right way to achieve portability over a wide
|> range of existing and future systems (including ones that have different
|> register sizes). The change to 128-bit is not going to affect this software
|> precisely because it already uses correctly sized types.

On the contrary. Look, how many word size changes have you been
through? Some of my code has been through about a dozen, in
succession, often with NO changes. Code that screws 32 bits in
will not be able to handle data that exceeds that.

It will work as long as the compiler supports a 32-bit type - which it will of
course. But in the infinitesimal chance it doesn't, why couldn't one
emulate a 32-bit type, just like 32-bit systems emulate 64-bit types?
You are making PRECISELY the mistake that was made by the people
who coded the exact sizes of the IBM System/360 into their programs.
They learnt better, but have been replaced by a new set of kiddies,
determined to make the same old mistake :-(

Actually various other languages support sized types and most software
used them long before C99. In many cases it is essential for correctness
(imagine writing 32 bits to a peripheral when it expects 16 bits etc). So
you really have to come up with some extraordinary evidence to explain
why you think sized types are fundamentally wrong.

Wilco
 
J

Jan Panteltje

Jan 1, 1970
0
|> >
|> >The length is passed around as uint32_t, but so are rather a lot of
|> >other fields. In a year or so, the program is upgraded to support
|> >another interface, which allows 48- or 64-bit file lengths.
|>
|> That is babble.
|> A new file specification will have an other header, or will be in
|> an extention field of the current header.
|> The whole program would be a different one, as all length calculations
|> and checks would change.
|> I have been there, done that.

Precisely. And, if you would learn from the experience of the past,
all you would have to change is the interface code - the rest of the
program would not even need inspecting.

Been there - done that. Many times, in many contexts.


Regards,
Nick Maclaren.

I know we can go on, but probably mean the same thing in the end,
but 'the program would not need inspecting (or changing)' sounds a
bit, eh, daring, if not wrong.
Take the example of a program that concatenates some wave files to
one larger one.
It will first read all headers, add the sizes, and then, if it finds the
output exceeds 4GB say: 'myprogram: output exceeds 4GB, aborting.'
So, the size check, and the reporting, would need to change, in any case.
However there is much more, depending how really pedantic one was in
reading the file headers, perhaps as
length = byte + (byte * 256) + (byte * 65536) + etc.
I do not claim to be the perfect coder, and you compiler writers
know more about the specs then I do, but - I do try to learn from these
discussions, and other similar ones in relevant newsgroups -.
It has caused me on several occasions to rewrite my code.
Will it ever be perfect? No, but usable, with no errors, yes.
When I get an email (this happened when AMD 64 came out) saying:
Your program always worked fine, but now I have an AMD 128, and it
reports the wrong output file size', what do I do now?' it
will be back to the source code for me, or somebody else.
 
Top