Does your C compiler support "//"? (was Re: using structures)

D

Douglas A. Gwyn

Paul said:
Apparently you misunderstood my point. Your post talked at length
about off_t, but I was referring to size_t, not off_t.

Only because external memory being cheaper than internal memory,
the problem showed up there first.
Every implementation that went through the introduction of "long long"
in the late 1980s and early 1990s -- and this was done precisely to
support "ever-increasing dataset sizes" with 64-bit architectures --
came up with a C89-compatible solution, i.e., a solution where size_t
was no wider than unsigned long. "Ever-increasing dataset sizes" thus
provided no practical justification for making such an incompatible
change to the C language.

Surely by now you have encountered platforms with > 4GB RAM.
This trend was predictable, and we decided to deal with it
as soon as we saw it coming.
 
F

Francis Glassborow

Douglas A. Gwyn said:
Only because external memory being cheaper than internal memory,
the problem showed up there first.


Surely by now you have encountered platforms with > 4GB RAM.
This trend was predictable, and we decided to deal with it
as soon as we saw it coming.

The issue of integer types and extended integer types has to be look ed
at from all sides.

Certain programmers wrote code that relied on long being the widest
integer type in C. A very large number of other programmers wrote code
that relied on long being 32-bits on the platforms they were using.

As time went by having the widest type restricted to 32-bits became
increasingly unacceptable to an ever increasing number of programmers.

Changing long to more than 32-bits breaks an assumed invariant in a
great deal of code. Breaking the invariant that long is the widest type
breaks a different body of code.

Now the argument is that the latter group were writing code that
conformed to their understanding of C89 (note that I really do not want
to waste time debating whether their understanding was correct, it is a
dry and entirely pointless argument) had right on their side whilst
those writing code where long was 32-bits should just accept that it
would not be.

But standards are about commerce (OK some are about safety but language
standards are of the former kind even if some would want it otherwise).
The commercial judgement was that it was more viable to allow types
longer that were wider than long.

The argument about long long is an entire red herring (actually I have
very strong reservations about any fundamental type having a multi-token
name, but that is a different issue). The fundamental issue is whether
the Standard should bless extended integer types wider than long to the
extent that they may be used via standard typedefs such as size_t and
off_t.

If such usage is an important issue for a larger enough minority of
customers then implementors will enhance their market share by avoiding
use of types wider than long for the standard typedefs.

If the minority is insufficient to apply commercial pressure then sadly
my response is 'tough' live with it. It is not the responsibility of a
Standard to protect the interest of such a minority at the expense of
the majority. This is neither an academic nor a political issue but a
commercial one.

BTW there is absolutely nothing under international treatise that
requires any NB to adopt an ISO/IEC standard as their own.

Also note that the overwhelming majority of C programmers do not use
their compilers in strictly conforming mode. I am sure that those
companies that have speciality markets (such as support for 8051 based
hardware) will continue to produce tools that meet those markets needs
(and as such ones that do not conform to any C Standard).

Yes, I want better standards but I also want standards that are
respected and largely used. That means that Standards do need to respond
to existing practice. I think that there are some areas of C99 that
would have, IMO, been better left as TRs (I think that much of the
complex number support might have been better left in a TR), and there
are some areas which could have used more work to provide a uniform
mechanism (I am thinking of such items as the type generic maths
support) but given the limited human resources available I think we did
a pretty good job with C99.

BTW IMHO a pre-requisite for criticising features of C99 (as opposed to
raising defect reports) should be having read the WG14 Rationale
document which explains many of the decisions. At least take time to
discover why, before objecting to the what.
 
P

pete

Jarno said:
I need the fastest type that can hold at least 32 bits. What
should I use?
long.
Is it really the fastest type that can hold at least 32 bits?
No, long is 64 bits and int is 32 bits. int is the fastest type.

I don't get what you mean by "type that can hold at least 32 bits"

In the same sense that int "can hold at least 32 bits",
so can short and char.
 
F

Francis Glassborow

[QUOTE="pete said:
I need the fastest type that can hold at least 32 bits. What
should I use?
long.
Is it really the fastest type that can hold at least 32 bits?
No, long is 64 bits and int is 32 bits. int is the fastest type.

I don't get what you mean by "type that can hold at least 32 bits"

In the same sense that int "can hold at least 32 bits",
so can short and char.[/QUOTE]

I know that there is a degree of ambiguity in using 'can' but it must be
blatantly obvious in context that he means he needs a type that can hold
32-bits in the implementation he is using. The only C89 types that can
hold 32-bits portably are the various flavours of long.
 
J

Jim

Randy said:
So, how are those MS stock options looking these days?

What sort of willful non-conformance would not supporting C99 a full
4 years after publication fall under btw? I can understand a lowly
open source package such as gcc (feel free to insert any of the other
FUD terms invented by Microsoft marketing to describe OSD here as
well) not supporting it by now, although they have made far, far more
progress than MS. Now, if Microsoft is really the reference standard
for professional software, how long should it take? Could it be
that they actually don't care at all about industry standards and in
fact eschew them at every opportunity?
Eschew? Overturn and subvert to their own secret standard
perhaps.

Jim
 
P

Paul Eggert

Only because external memory being cheaper than internal memory,
the problem showed up there first.

Yes, and the same point was obvious to everyone at the time "long
long" was introduced (circa 1990), and implementers all came up with
solutions that solve the problem without breaking the C89 guarantees.
So there was (and is) no practical justfication for this incompatible
change to the standard.

Surely by now you have encountered platforms with > 4GB RAM.

Absolutely. And they all, without exception, have size_t values that
are no wider than long. This is all well-understood; it is a problem
that has been solved for more than a decade.

This trend was predictable, and we decided to deal with it
as soon as we saw it coming.

You decided to deal with something that was not a problem in practice.
You made an incompatible change to the standard, a change that allows
behavior that wasn't common existing practice, a change that breaks
many real-world C programs in subtle ways that are hard to find.
This was a blunder.
 
J

Jarno A Wuolijoki

I don't get what you mean by "type that can hold at least 32 bits"

Ah. Excuse my wording:
I meant one that /is guaranteed to be/ at least 32 bits wide on all
platforms.

Just ranting. A platform where int takes 32 bits and long 64
is (pick an expletive): the word size is 32 bits but there's
no simple portable way to access it. Thus majority of programs
will suffer.
 
P

Paul Eggert

The commercial judgement was that it was more viable to
allow types longer that were wider than long.

But the commercial judgment was that size_t should be no wider than long.
Why did the C committee overrule that existing practice, and
invalidate existing programs?
Yes, I want better standards but I also want standards that are
respected and largely used. That means that Standards do need to
respond to existing practice.

This is precisely the point! In this case I am complaining about an
incompatible change to the standard that was not in response to
existing practice.
a pre-requisite for criticising features of C99 (as opposed
to raising defect reports) should be having read the WG14 Rationale
document which explains many of the decisions.

The rationale does not explain or justify this decision to break
existing code. It talks merely about ILP32LL (in two flavors) and
LP64; none of these environments have size_t wider than long.
Changing long to more than 32-bits breaks an assumed invariant in a
great deal of code.

This was a problem in 1990 perhaps, but it stopped being a problem
long ago in any code that attempts to be portable to 64-bit platforms,
because they all used 64-bit 'long' starting around then.

It was quite odd of the committee to change the standard to support
code that was always broken, and that was obsolete by 1991, while in
the process breaking a wide variety of more modern code that was fully
supported by C89.
 
D

Douglas A. Gwyn

Paul said:
This was a blunder.

I could keep arguing, but it seems clear that neither of us
is likely to change his opinion, and all the major arguments
seem to have already been made at least once.
 
J

James Kuyper

Douglas A. Gwyn said:
I suggest just
#include "stdint.h"

My company's coding standards require that standard headers be #included
using "<>", and I agree. I have no intention of trying to write code for
compilers that don't fully conform to at least one standard, either C89,
C++98, or C99.
You can always provide your own implementation of stdint.h
if the platform doesn't already have one. You may recall
that I even made one available on the Lysator C site many
years ago.

That's a more comprehensive way of implementing the same idea; in
essense, I was describing the kind of thing that should be in such an
implmentation. However, for my own use I'd insist that if it's not being
picked up from the standard library's directory, then it should have a
name that differs from any standard library header, and should be
#included using "", rather than <>. I think that imperfectly emulating
something can be dangerous. The danger can be reduced (but not
eliminated) by clearly labelling it as such.

<stdint.h> has some characteristics that cannot be portably implemented
exactly the way they're supposed to be. For example, there's no way that
a "stdint.h" could guarantee correctly identifying the fastest type of a
given size. On some platforms, meeting the standard's requirements would
require using an extended type, rather than a standard type, for one or
more to the <stdint.h> typedefs. No portable "stdint.h" could correctly
implement such typedefs.

I'm not saying a "stdint.h" wouldn't be worthwhile, merely that I'd give
it a different name, to avoid confusion with the real thing.
 
J

James Kuyper

Douglas A. Gwyn said:
In fact many such typedefs in interfaces on large platforms
were already using extended integer types wider than long.
While in a C90 DR response the committee was forced to say,
by a strict reading of the rules, that none of the typedefs
in the C standard could use an extended integer type, this
didn't apply to other typedefs. Obviously there could be

Yes it did. No strictly conforming code could use an extended integer
type, because C90 didn't have extended integer types. I'm not interested
in code that won't compile when I use my compiler in it's conforming
mode, and I don't care what problems might be caused by such code.

....
Works the same everywhere under the same conditions, namely
those under which the function would return a value that can
be represented in type long int. Wouldn't work anywhere
under conditions where that wasn't true.

Yes. And those conditions could never come up under a conforming
implementation of C90. It can break under a conforming implementation of
C99. This particular third-party library is subject to the same
constraints as our code; it must compile when using a C90-conforming
compiler when running in its strict ANSI conformance mode. The day that
requirement gets updated to refer to C99, an awful lot of my code is
going to become dangerous.

....
Wrong. I provided the very first program I laid my hands on,
which turned out to have one *bug* in that it didn't check for
argc==0, easily fixed and irrelevant to the issue of whether a
s.c. program could be a useful one.

I don't want to bother looking up again what that particular program
was, but the fact that it had a bug like that in it was merely amusing,
it wasn't the main point. I'm fairly certain that the main point against
it's strict conformance was that it used I/O, like most useful programs
do. It's impossible to use the standard C I/O system without invoking
implementation-defined (or worse) behavior. I realize that you're in
denial about the relevance of that fact, which doesn't change the fact
that it is relevant.

A useful strictly conforming C program could, in principle, communicate
with the outside world by returning either a successful or unsuccessful
exit status, but trying to return three different exit statuses enters
into implementation-defined territory. A program which can't take in any
input, and is restricted to 1 bit of output, isn't very likely to be
very useful. It is, in fact possible for such a program to be useful,
which is why I was suprised when you failed to provide one. However,
having to use the exit status as the only method of communication would
have implicitly conceded that the other methods have
implementation-defined behavior, so I suppose you didn't see that as an
option.
 
D

Douglas A. Gwyn

\> My company's coding standards require that standard headers be #included
using "<>", and I agree. I have no intention of trying to write code for
compilers that don't fully conform to at least one standard, either C89,
C++98, or C99.

I don't think you understood. On a *C89* conforming platform,
#include "stdint.h" will include the implementation that *you*
provide with the rest of your source files. On a *C99*
conforming platform, you don't put that file where it will be
seen by the compiler, and then #include "stdint.h" will access
the *C implementation's* version. There is no need to have a
kludge around this in (potentially) every C source file.

I've found that #include "..." even for ytraditional standard
headers is a very useful practice, since it provides a way to
work around deficiencies in whatever a particular platform
might have supplied. I have even found problems in Solaris
standard headers when a reasonable amount of lint-like
warnings are enabled during compilation.
However, for my own use I'd insist that if it's not being
picked up from the standard library's directory, then it should have a
name that differs from any standard library header, and should be
#included using "", rather than <>.

You can do that, but then you have added another set of
conventions (typedef names etc.) that burden the programmer.
When the C99 standard facilities will work, why not just
make them available when that is especially feasible (as
it is for the case in point)?
<stdint.h> has some characteristics that cannot be portably implemented
exactly the way they're supposed to be.

The implementation of "stdint.h" doesn't have to be portable
in the sense that no tweaks are needed to tailor it for a new
platform. The one I use has some parameters that need to be
set for each target platform, and those are used to build the
appropriate typedefs. But you could also significantly
streamline it by just having a separate version per platform
with no intermediate parameters.
For example, there's no way that
a "stdint.h" could guarantee correctly identifying the fastest type of a
given size.

That whole notion is problematic in the first place, and we
had to negotiate a fine compromise to get a consensus for its
inclusion in the standard.
On some platforms, meeting the standard's requirements would
require using an extended type, rather than a standard type, for one or
more to the <stdint.h> typedefs.

That's right. So do it that way.
 
D

Douglas A. Gwyn

James said:
:
Yes it did. No strictly conforming code could use an extended integer
type, because C90 didn't have extended integer types.

We were talking about typedefs in third-party library interfaces.
The library *user* is not in a position to say whether or not
their use constitutes non-strict conformance. The library
*implementor* may well have good reason to use an extended type.
Yes. And those conditions could never come up under a conforming
implementation of C90.

Yes, it could..
... This particular third-party library is subject to the same
constraints as our code; it must compile when using a C90-conforming
compiler when running in its strict ANSI conformance mode.

That's new information. Generally speaking, one cannot count
on that for third-party libraries.
> The day that
requirement gets updated to refer to C99, an awful lot of my code is
going to become dangerous.

? You've had at least 5 years to convert to intmax_t etc.
... It's impossible to use the standard C I/O system without invoking
implementation-defined (or worse) behavior. I realize that you're in
denial about the relevance of that fact, which doesn't change the fact
that it is relevant.

It's not a fact, it's an erroneous claim made by people whose
only interest in the C standard is in finding fault with it,
even if they have to invent problems. Other members of the C
standards committee have been in general agreement with me
about the ability to use I/O in strictly conforming programs.
We even generalized this for C99 so that locale-specific
characteristics can be utilized in the output of s.c. programs.
... A program which can't take in any
input, and is restricted to 1 bit of output, isn't very likely to be
very useful. It is, in fact possible for such a program to be useful,
which is why I was suprised when you failed to provide one.

Do you know what a "straw man" is? I don't care to provide a
program like that, because that would appear to support the
totally erroneous notion that a s.c. program cannot perform
useful I/O.
 
A

Al Grant

Douglas A. Gwyn said:
It's not a fact, it's an erroneous claim made by people whose
only interest in the C standard is in finding fault with it,
even if they have to invent problems. Other members of the C
standards committee have been in general agreement with me
about the ability to use I/O in strictly conforming programs.

Have any of them ever written one?
 
J

James Kuyper

Douglas A. Gwyn said:
\> My company's coding standards require that standard headers be #included

I don't think you understood. On a *C89* conforming platform,
#include "stdint.h" will include the implementation that *you*
provide with the rest of your source files. On a *C99*
conforming platform, you don't put that file where it will be
seen by the compiler, and then #include "stdint.h" will access
the *C implementation's* version.

I understood that fully. I'm neither allowed, nor willing, to deliver
code that contains header files which need to be hidden under some
circumstances, but not in others.
... There is no need to have a
kludge around this in (potentially) every C source file.

I agree, putting it in a seperate file is a better solution. I just
would not give it a name that conflicts with the standard header that it
(necessarily) imperfectly emulates. If the emulation could be perfect,
then I wouldn't mind.
The implementation of "stdint.h" doesn't have to be portable

But the code I deliver does. Therefore, I can't deliver a "stdint.h"
with my code.
 
J

James Kuyper

Douglas A. Gwyn said:
We were talking about typedefs in third-party library interfaces.
The library *user* is not in a position to say whether or not
their use constitutes non-strict conformance. The library
*implementor* may well have good reason to use an extended type.

This particular third party is subject to the same contract constraints
that we are; as soon as we're permitted to use C99, so will they.
 
D

Douglas A. Gwyn

James said:
But the code I deliver does. Therefore, I can't deliver a "stdint.h"
with my code.

There is no other *portable* way to deliver e.g. "fastest
unsigned integer type width width no less than 32 bits"
within just the C application itself. A reasonable way
to design C applications is: (1) portable source for the
bulk of the application; (2) a platform adaptive interface
layer whose API is the same everywhere but whose internals
are platform-specific; (3) a conforming implementation of
Standard C along with some platform-specific extensions
that are used only in your interface layer.
 
J

James Kuyper

Douglas A. Gwyn said:
There is no other *portable* way to deliver e.g. "fastest
unsigned integer type width width no less than 32 bits"
within just the C application itself. A reasonable way
to design C applications is: (1) portable source for the
bulk of the application; (2) a platform adaptive interface
layer whose API is the same everywhere but whose internals
are platform-specific; (3) a conforming implementation of
Standard C along with some platform-specific extensions
that are used only in your interface layer.

I am not allowed to do that in my delivered code. I'm allowed to
assume C90 and POSIX conformance, and the presence of five specific
third-party libraries, but nothing else. Our data files are portable
because one of those libraries uses that method internally (though
XDR); but my own code is not allowed to do so.
 
D

Douglas A. Gwyn

James said:
I am not allowed to do that in my delivered code. ...

Well, the more constraints that are added, the less optimum
is the best feasible solution.
 

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
473,776
Messages
2,569,603
Members
45,196
Latest member
TopCryptoTxSoftwares2024

Latest Threads

Top